From 37b3a63ae609b76e7a228d20aaa149dd11fdeb7b Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 23 Jun 2025 19:48:13 +0200 Subject: [PATCH 1/8] feat: initialized template --- .gitignore | 12 ++++++-- justfile | 2 +- modules/PROJECT/register_types.cpp | 15 ---------- modules/PROJECT/register_types.h | 9 ------ modules/{PROJECT => authority}/SCsub | 0 .../__pycache__/config.cpython-313.pyc | Bin 0 -> 390 bytes modules/{PROJECT => authority}/config.py | 0 modules/{PROJECT => authority}/macros.h | 0 modules/authority/register_types.cpp | 26 ++++++++++++++++++ modules/authority/register_types.h | 9 ++++++ project/export_presets.cfg | 4 +-- project/project.godot | 2 +- 12 files changed, 48 insertions(+), 31 deletions(-) delete mode 100644 modules/PROJECT/register_types.cpp delete mode 100644 modules/PROJECT/register_types.h rename modules/{PROJECT => authority}/SCsub (100%) create mode 100644 modules/authority/__pycache__/config.cpython-313.pyc rename modules/{PROJECT => authority}/config.py (100%) rename modules/{PROJECT => authority}/macros.h (100%) create mode 100644 modules/authority/register_types.cpp create mode 100644 modules/authority/register_types.h diff --git a/.gitignore b/.gitignore index b8680775..3f82628a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,16 @@ # When configure fails, SCons outputs these config.log .sconf_temp +.config + +# build artefacts +.cache/ +*.o +compile_commands.json engine/.github project/.godot -build/PROJECT.pck -build/PROJECT.x86_64 -build/PROJECT.exe +build/authority.pck +build/authority.x86_64 +build/authority.exe build.zip diff --git a/justfile b/justfile index ad0c5d09..48c61a88 100644 --- a/justfile +++ b/justfile @@ -1,6 +1,6 @@ set export -BUILD_NAME := "change_me" +BUILD_NAME := "authority" build: format # Compiling Editor diff --git a/modules/PROJECT/register_types.cpp b/modules/PROJECT/register_types.cpp deleted file mode 100644 index a367b16d..00000000 --- a/modules/PROJECT/register_types.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "register_types.h" - -#include "core/object/class_db.h" - -void initialize_PROJECT_module(ModuleInitializationLevel p_level) { - if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { - return; - } -} - -void uninitialize_PROJECT_module(ModuleInitializationLevel p_level) { - if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { - return; - } -} diff --git a/modules/PROJECT/register_types.h b/modules/PROJECT/register_types.h deleted file mode 100644 index 2a1d0257..00000000 --- a/modules/PROJECT/register_types.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PROJECT_REGISTER_TYPES_H -#define PROJECT_REGISTER_TYPES_H - -#include "modules/register_module_types.h" - -void initialize_PROJECT_module(ModuleInitializationLevel p_level); -void uninitialize_PROJECT_module(ModuleInitializationLevel p_level); - -#endif // !PROJECT_REGISTER_TYPES_H diff --git a/modules/PROJECT/SCsub b/modules/authority/SCsub similarity index 100% rename from modules/PROJECT/SCsub rename to modules/authority/SCsub diff --git a/modules/authority/__pycache__/config.cpython-313.pyc b/modules/authority/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d3597edc0190babb3bd28785427ea2442f0faea GIT binary patch literal 390 zcmey&%ge>Uz`*b)C^Ey3fq~&Mhy%lnP{wBg1_p+y48aUi3`GpVj8Y6mjOk38%*jkp zc@PCs%gn&Q@R~wiuDsqOEU6{GD|A;bMsS5b5fB-lJoP@GSl@6 zDsOQnC+5W`m1gFo6tOcfFo2v<%*w#P(7-BH#?QdO@PV0;k?|7~BctGFHbzD+um%A0-A^|F literal 0 HcmV?d00001 diff --git a/modules/PROJECT/config.py b/modules/authority/config.py similarity index 100% rename from modules/PROJECT/config.py rename to modules/authority/config.py diff --git a/modules/PROJECT/macros.h b/modules/authority/macros.h similarity index 100% rename from modules/PROJECT/macros.h rename to modules/authority/macros.h diff --git a/modules/authority/register_types.cpp b/modules/authority/register_types.cpp new file mode 100644 index 00000000..4a3fe411 --- /dev/null +++ b/modules/authority/register_types.cpp @@ -0,0 +1,26 @@ +#include "register_types.h" + +#include "authority/game_state.h" +#include "core/config/engine.h" +#include "core/object/class_db.h" + +GameState *game_state{nullptr}; + +void initialize_authority_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { + return; + } + GDREGISTER_CLASS(GameState); + + game_state = memnew(GameState); + Engine::get_singleton()->add_singleton(Engine::Singleton("GameState", GameState::get_singleton())); +} + +void uninitialize_authority_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { + return; + } + if(game_state) { + memdelete(game_state); + } +} diff --git a/modules/authority/register_types.h b/modules/authority/register_types.h new file mode 100644 index 00000000..d55a194f --- /dev/null +++ b/modules/authority/register_types.h @@ -0,0 +1,9 @@ +#ifndef authority_REGISTER_TYPES_H +#define authority_REGISTER_TYPES_H + +#include "modules/register_module_types.h" + +void initialize_authority_module(ModuleInitializationLevel p_level); +void uninitialize_authority_module(ModuleInitializationLevel p_level); + +#endif // !authority_REGISTER_TYPES_H diff --git a/project/export_presets.cfg b/project/export_presets.cfg index a04762ac..fae5030f 100644 --- a/project/export_presets.cfg +++ b/project/export_presets.cfg @@ -9,7 +9,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="../build/PROJECT.x86_64" +export_path="../build/authority.x86_64" patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" @@ -51,7 +51,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="../build/PROJECT.exe" +export_path="../build/authority.exe" patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" diff --git a/project/project.godot b/project/project.godot index bd5ab3b0..8cd51d29 100644 --- a/project/project.godot +++ b/project/project.godot @@ -10,6 +10,6 @@ config_version=5 [application] -config/name="PROJECT" +config/name="authority" config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://icon.svg" From f6e6cf9e55f07ca4a942085d9fa2af7f636363a6 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 23 Jun 2025 19:48:33 +0200 Subject: [PATCH 2/8] feat: set engine version to latest 4.4 --- engine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine b/engine index 215acd52..e531f3eb 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit 215acd52e82f4c575abb715e25e54558deeef998 +Subproject commit e531f3eb7b13a9adaaf5b15ac9b3aebc4c2030cd From 1828ebbe21514400c682e4e70d1624da79daa2d8 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 23 Jun 2025 19:48:52 +0200 Subject: [PATCH 3/8] feat: first game code --- modules/authority/game_state.cpp | 24 ++++++++++++++ modules/authority/game_state.h | 21 +++++++++++++ modules/authority/locale_marker.cpp | 49 +++++++++++++++++++++++++++++ modules/authority/locale_marker.h | 25 +++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 modules/authority/game_state.cpp create mode 100644 modules/authority/game_state.h create mode 100644 modules/authority/locale_marker.cpp create mode 100644 modules/authority/locale_marker.h diff --git a/modules/authority/game_state.cpp b/modules/authority/game_state.cpp new file mode 100644 index 00000000..8f0a1c5c --- /dev/null +++ b/modules/authority/game_state.cpp @@ -0,0 +1,24 @@ +#include "game_state.h" +#include "macros.h" + +void GameState::_bind_methods() { + BIND_PROPERTY(Variant::STRING, locale_uid); + BIND_PROPERTY(Variant::STRING, locale_entrance_path); +} + +void GameState::set_locale_uid(String const &value) { + this->locale_uid = value; +} + +String GameState::get_locale_uid() const { + return this->locale_uid; +} + +void GameState::set_locale_entrance_path(String const &value) { + this->locale_uid = value; +} + +String GameState::get_locale_entrance_path() const { + return this->locale_uid; +} + diff --git a/modules/authority/game_state.h b/modules/authority/game_state.h new file mode 100644 index 00000000..f1bac503 --- /dev/null +++ b/modules/authority/game_state.h @@ -0,0 +1,21 @@ +#ifndef GAME_STATE_H +#define GAME_STATE_H + +#include "core/object/object.h" +#include "core/object/class_db.h" + +class GameState : public Object { + GDCLASS(GameState, Object); + static void _bind_methods(); +public: + static GameState *get_singleton(); + void set_locale_uid(String const &value); + String get_locale_uid() const; + void set_locale_entrance_path(String const &value); + String get_locale_entrance_path() const; +private: + String locale_uid{""}; + String locale_entrance_path{""}; +}; + +#endif // !GAME_STATE_H diff --git a/modules/authority/locale_marker.cpp b/modules/authority/locale_marker.cpp new file mode 100644 index 00000000..9cd169b8 --- /dev/null +++ b/modules/authority/locale_marker.cpp @@ -0,0 +1,49 @@ +#include "locale_marker.h" +#include "authority/game_state.h" +#include "core/config/engine.h" +#include "core/input/input_enums.h" +#include "macros.h" + +void LocaleMarker::_bind_methods() { + BIND_HPROPERTY(Variant::STRING, locale_scene, PROPERTY_HINT_FILE, "*.tscn,*.scn"); +} + +void LocaleMarker::_notification(int what) { + if(Engine::get_singleton()->is_editor_hint()) { + return; + } + switch(what) { + default: return; + case NOTIFICATION_READY: + this->ready(); + return; + } +} + +void LocaleMarker::ready() { + this->connect(this->sig_input_event, callable_mp(this, &self_type::on_input_event)); +} + +void LocaleMarker::on_input_event(Node *camera, Ref event, Vector3 position, Vector3 normal, int shape_ind) { + Ref clicked{event}; + if(clicked.is_valid() && clicked->get_button_index() == MouseButton::LEFT) { + GameState::get_singleton()->set_locale_entrance_path(this->entrance_path); + GameState::get_singleton()->set_locale_uid(locale_scene); + } +} + +void LocaleMarker::set_locale_scene(String const &path) { + this->locale_scene = path; +} + +String LocaleMarker::get_locale_scene() const { + return this->locale_scene; +} + +void LocaleMarker::set_entrance_path(String const &node_path) { + this->entrance_path = node_path; +} + +String LocaleMarker::get_entrance_path() const { + return this->entrance_path; +} diff --git a/modules/authority/locale_marker.h b/modules/authority/locale_marker.h new file mode 100644 index 00000000..1020df96 --- /dev/null +++ b/modules/authority/locale_marker.h @@ -0,0 +1,25 @@ +#ifndef LOCALE_MARKER_H +#define LOCALE_MARKER_H + +#include "core/input/input_event.h" +#include "scene/3d/physics/area_3d.h" +#include "scene/main/node.h" + +class LocaleMarker : public Area3D { + GDCLASS(LocaleMarker, Area3D); + static void _bind_methods(); + void _notification(int what); + void ready(); + void on_input_event(Node *camera, Ref event, Vector3 position, Vector3 normal, int shape_ind); +public: + void set_locale_scene(String const &value); + String get_locale_scene() const; + void set_entrance_path(String const &value); + String get_entrance_path() const; +private: + String locale_scene{"res://"}; + String entrance_path{"%"}; + String const sig_input_event{"input_event"}; +}; + +#endif // !LOCALE_MARKER_H From 8d07ee03fae7d841220e2a6c221ee58edfa9057b Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 24 Jun 2025 14:20:06 +0200 Subject: [PATCH 4/8] feat: implemented singleton fully for game state --- modules/authority/game_state.cpp | 15 ++++++++++++++- modules/authority/game_state.h | 11 ++++++++--- modules/authority/locale_marker.cpp | 20 +++++++++++--------- modules/authority/locale_marker.h | 8 +++++--- modules/authority/register_types.cpp | 4 ++-- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/modules/authority/game_state.cpp b/modules/authority/game_state.cpp index 8f0a1c5c..026b13eb 100644 --- a/modules/authority/game_state.cpp +++ b/modules/authority/game_state.cpp @@ -1,11 +1,25 @@ #include "game_state.h" #include "macros.h" +GameState *GameState::singleton_instance{ nullptr }; + void GameState::_bind_methods() { BIND_PROPERTY(Variant::STRING, locale_uid); BIND_PROPERTY(Variant::STRING, locale_entrance_path); } +GameState::GameState() { + self_type::singleton_instance = this; +} + +GameState::~GameState() { + self_type::singleton_instance = nullptr; +} + +GameState *GameState::get_singleton() { + return self_type::singleton_instance; +} + void GameState::set_locale_uid(String const &value) { this->locale_uid = value; } @@ -21,4 +35,3 @@ void GameState::set_locale_entrance_path(String const &value) { String GameState::get_locale_entrance_path() const { return this->locale_uid; } - diff --git a/modules/authority/game_state.h b/modules/authority/game_state.h index f1bac503..a818357d 100644 --- a/modules/authority/game_state.h +++ b/modules/authority/game_state.h @@ -1,21 +1,26 @@ #ifndef GAME_STATE_H #define GAME_STATE_H -#include "core/object/object.h" #include "core/object/class_db.h" +#include "core/object/object.h" class GameState : public Object { GDCLASS(GameState, Object); static void _bind_methods(); + static GameState *singleton_instance; + public: + GameState(); + virtual ~GameState(); static GameState *get_singleton(); void set_locale_uid(String const &value); String get_locale_uid() const; void set_locale_entrance_path(String const &value); String get_locale_entrance_path() const; + private: - String locale_uid{""}; - String locale_entrance_path{""}; + String locale_uid{ "" }; + String locale_entrance_path{ "" }; }; #endif // !GAME_STATE_H diff --git a/modules/authority/locale_marker.cpp b/modules/authority/locale_marker.cpp index 9cd169b8..0ea4e2b8 100644 --- a/modules/authority/locale_marker.cpp +++ b/modules/authority/locale_marker.cpp @@ -9,14 +9,15 @@ void LocaleMarker::_bind_methods() { } void LocaleMarker::_notification(int what) { - if(Engine::get_singleton()->is_editor_hint()) { + if (Engine::get_singleton()->is_editor_hint()) { return; } - switch(what) { - default: return; - case NOTIFICATION_READY: - this->ready(); - return; + switch (what) { + default: + return; + case NOTIFICATION_READY: + this->ready(); + return; } } @@ -25,10 +26,11 @@ void LocaleMarker::ready() { } void LocaleMarker::on_input_event(Node *camera, Ref event, Vector3 position, Vector3 normal, int shape_ind) { - Ref clicked{event}; - if(clicked.is_valid() && clicked->get_button_index() == MouseButton::LEFT) { + Ref clicked{ event }; + if (clicked.is_valid() && clicked->get_button_index() == MouseButton::LEFT) { + GameState::get_singleton()->set_locale_uid(this->locale_scene); GameState::get_singleton()->set_locale_entrance_path(this->entrance_path); - GameState::get_singleton()->set_locale_uid(locale_scene); + get_tree()->change_scene_to_file(this->locale_scene); } } diff --git a/modules/authority/locale_marker.h b/modules/authority/locale_marker.h index 1020df96..15295510 100644 --- a/modules/authority/locale_marker.h +++ b/modules/authority/locale_marker.h @@ -11,15 +11,17 @@ class LocaleMarker : public Area3D { void _notification(int what); void ready(); void on_input_event(Node *camera, Ref event, Vector3 position, Vector3 normal, int shape_ind); + public: void set_locale_scene(String const &value); String get_locale_scene() const; void set_entrance_path(String const &value); String get_entrance_path() const; + private: - String locale_scene{"res://"}; - String entrance_path{"%"}; - String const sig_input_event{"input_event"}; + String locale_scene{ "res://" }; + String entrance_path{ "%" }; + String const sig_input_event{ "input_event" }; }; #endif // !LOCALE_MARKER_H diff --git a/modules/authority/register_types.cpp b/modules/authority/register_types.cpp index 4a3fe411..a1486643 100644 --- a/modules/authority/register_types.cpp +++ b/modules/authority/register_types.cpp @@ -4,7 +4,7 @@ #include "core/config/engine.h" #include "core/object/class_db.h" -GameState *game_state{nullptr}; +GameState *game_state{ nullptr }; void initialize_authority_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { @@ -20,7 +20,7 @@ void uninitialize_authority_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } - if(game_state) { + if (game_state) { memdelete(game_state); } } From 80a948686f7fbabaf62ef180d67f0a80f5dc41c1 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 25 Jun 2025 13:48:55 +0200 Subject: [PATCH 5/8] feat: started designing monarchist camp locale --- design/monarchist_camp.svg | 183 ++++++++ modules/authority/locale_marker.cpp | 1 + modules/authority/register_types.cpp | 2 + project/level_props/tent.tscn | 13 + project/locales/city.tscn | 574 +++++++++++++++++++++++ project/maps/map.tscn | 126 +++++ project/materials/grids/bricks.tres | 7 + project/materials/grids/grass.tres | 7 + project/materials/grids/mud.tres | 7 + project/materials/grids/tent.tres | 7 + project/project.godot | 1 + project/textures/grids/bricks.png | Bin 0 -> 18043 bytes project/textures/grids/bricks.png.import | 35 ++ project/textures/grids/grass.png | Bin 0 -> 20088 bytes project/textures/grids/grass.png.import | 35 ++ project/textures/grids/mud.png | Bin 0 -> 15859 bytes project/textures/grids/mud.png.import | 35 ++ project/textures/grids/rock.png | Bin 0 -> 16603 bytes project/textures/grids/rock.png.import | 34 ++ project/textures/grids/tent.png | Bin 0 -> 14927 bytes project/textures/grids/tent.png.import | 35 ++ 21 files changed, 1102 insertions(+) create mode 100644 design/monarchist_camp.svg create mode 100644 project/level_props/tent.tscn create mode 100644 project/locales/city.tscn create mode 100644 project/maps/map.tscn create mode 100644 project/materials/grids/bricks.tres create mode 100644 project/materials/grids/grass.tres create mode 100644 project/materials/grids/mud.tres create mode 100644 project/materials/grids/tent.tres create mode 100644 project/textures/grids/bricks.png create mode 100644 project/textures/grids/bricks.png.import create mode 100644 project/textures/grids/grass.png create mode 100644 project/textures/grids/grass.png.import create mode 100644 project/textures/grids/mud.png create mode 100644 project/textures/grids/mud.png.import create mode 100644 project/textures/grids/rock.png create mode 100644 project/textures/grids/rock.png.import create mode 100644 project/textures/grids/tent.png create mode 100644 project/textures/grids/tent.png.import diff --git a/design/monarchist_camp.svg b/design/monarchist_camp.svg new file mode 100644 index 00000000..23a1e008 --- /dev/null +++ b/design/monarchist_camp.svg @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/authority/locale_marker.cpp b/modules/authority/locale_marker.cpp index 0ea4e2b8..1bc7efec 100644 --- a/modules/authority/locale_marker.cpp +++ b/modules/authority/locale_marker.cpp @@ -6,6 +6,7 @@ void LocaleMarker::_bind_methods() { BIND_HPROPERTY(Variant::STRING, locale_scene, PROPERTY_HINT_FILE, "*.tscn,*.scn"); + BIND_PROPERTY(Variant::STRING, entrance_path); } void LocaleMarker::_notification(int what) { diff --git a/modules/authority/register_types.cpp b/modules/authority/register_types.cpp index a1486643..4d0c421a 100644 --- a/modules/authority/register_types.cpp +++ b/modules/authority/register_types.cpp @@ -1,6 +1,7 @@ #include "register_types.h" #include "authority/game_state.h" +#include "authority/locale_marker.h" #include "core/config/engine.h" #include "core/object/class_db.h" @@ -11,6 +12,7 @@ void initialize_authority_module(ModuleInitializationLevel p_level) { return; } GDREGISTER_CLASS(GameState); + GDREGISTER_CLASS(LocaleMarker); game_state = memnew(GameState); Engine::get_singleton()->add_singleton(Engine::Singleton("GameState", GameState::get_singleton())); diff --git a/project/level_props/tent.tscn b/project/level_props/tent.tscn new file mode 100644 index 00000000..065f9c5c --- /dev/null +++ b/project/level_props/tent.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://dkgep77ogr1tv"] + +[ext_resource type="Material" uid="uid://cupy5mpdsngcl" path="res://materials/grids/tent.tres" id="1_yfc7x"] + +[sub_resource type="BoxMesh" id="BoxMesh_dudpm"] +size = Vector3(3, 1.3, 2) + +[node name="Tent" type="Node3D"] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.658981, 0) +material_override = ExtResource("1_yfc7x") +mesh = SubResource("BoxMesh_dudpm") diff --git a/project/locales/city.tscn b/project/locales/city.tscn new file mode 100644 index 00000000..2e304ffc --- /dev/null +++ b/project/locales/city.tscn @@ -0,0 +1,574 @@ +[gd_scene load_steps=6 format=3 uid="uid://bqaoxvqgrbi3v"] + +[ext_resource type="Material" uid="uid://cbuk8uxxuj7j5" path="res://materials/grids/grass.tres" id="1_etye1"] +[ext_resource type="Material" uid="uid://ke4yek3xtin5" path="res://materials/grids/bricks.tres" id="1_sb1vi"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_sb1vi"] +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_vuk2b"] +sky_material = SubResource("ProceduralSkyMaterial_sb1vi") + +[sub_resource type="Environment" id="Environment_wwygw"] +background_mode = 2 +sky = SubResource("Sky_vuk2b") +tonemap_mode = 2 +glow_enabled = true + +[node name="City" type="Node3D"] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_wwygw") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) +shadow_enabled = true + +[node name="CSGWorld" type="CSGCombiner3D" parent="."] +use_collision = true + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.7726, 1.24028, -3.26613) +size = Vector3(29.3063, 2.53036, 32.2042) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +operation = 2 +size = Vector3(28.3818, 4.94897, 31.2627) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.3707, 0, 8.21931) +operation = 2 +size = Vector3(5.48248, 4.94897, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(0.996095, -0.0882858, 0, 0.0882858, 0.996095, 0, 0, 0, 1, -4.27235, 1.64007, -16.0551) +operation = 2 +size = Vector3(17.209, 2.77515, 1.67773) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D11" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(-0.662908, 0.748701, 0, -0.748701, -0.662908, 0, 0, 0, 1, 1.99536, 0.140041, -16.0551) +operation = 2 +size = Vector3(3.51099, 4.26892, 1.67773) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D12" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(0.0515306, -0.596407, 0.801026, -0.589269, -0.665739, -0.45777, 0.806292, -0.448431, -0.38575, 13.6247, 0.402275, -15.0203) +operation = 2 +size = Vector3(4.65393, 4.26892, 4.29919) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(1, 0, 0, 0, 0.990234, 0.139415, 0, -0.139415, 0.990234, -15.0347, 1.84148, -10.1624) +operation = 2 +size = Vector3(5.48248, 4.94897, 15.628) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(0.996356, 0.0852952, 0, -0.0852952, 0.996356, 0, 0, 0, 1, -6.08641, 2.3849, 15.0748) +operation = 2 +size = Vector3(18.0761, 4.49255, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D13" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(0.940934, 0.33859, 0, -0.33859, 0.940934, 0, 0, 0, 1, 10.9771, 1.22338, 15.0748) +operation = 2 +size = Vector3(5.48767, 4.49255, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(0.998184, -0.0602297, 0, 0.0602297, 0.998184, 0, 0, 0, 1, -11.169, 1.83497, 16.5285) +operation = 2 +size = Vector3(7.92215, 4.49255, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +transform = Transform3D(0.938076, -0.346428, 0, 0.346428, 0.938076, 0, 0, 0, 1, -8.1568, 0.67643, 16.5285) +operation = 2 +size = Vector3(4.54713, 4.49255, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 17.3635, 1.24027, -22.297) +size = Vector3(29.3063, 2.53036, 32.2042) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +operation = 2 +size = Vector3(28.3818, 4.94897, 31.2627) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.3707, 0, 8.21931) +operation = 2 +size = Vector3(5.48248, 4.94897, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.67738, 1.90735e-06, -15.8587) +operation = 2 +size = Vector3(11.8087, 4.94897, 1.39062) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +transform = Transform3D(0.983341, 0.181772, 0, -0.181772, 0.983341, 0, 0, 0, 1, 5.71055, 0.339279, 15.5698) +operation = 2 +size = Vector3(9.78, 4.23425, 1.39062) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -14.4351, 1.90735e-06, -3.8005) +operation = 2 +size = Vector3(11.8087, 4.94897, 1.39062) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +transform = Transform3D(0.835299, 0.549796, 0, -0.549796, 0.835299, 0, 0, 0, 1, -2.58652, 1.00152, -15.8587) +operation = 2 +size = Vector3(2.53568, 4.46423, 1.39062) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +transform = Transform3D(0.835299, 0.549796, -9.2008e-09, -0.491933, 0.747388, 0.446557, 0.245515, -0.373009, 0.894755, -14.5944, -0.54182, -15.1699) +operation = 2 +size = Vector3(3, 4.46423, 2.88232) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(0.94881, 0, 0.315848, 0, 1, 0, -0.315848, 0, 0.94881, -7.66859, 1.24028, 32.2569) +size = Vector3(22.6908, 2.53036, 26.0577) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +operation = 2 +size = Vector3(21.699, 4.94897, 24.7637) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) +operation = 2 +size = Vector3(5.48248, 4.94897, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D12" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(0.966641, 0.256107, 0.00379327, -0.221096, 0.841791, -0.492448, -0.129312, 0.475181, 0.870333, 10.1198, 1.29747, 12.165) +operation = 2 +size = Vector3(5.48248, 4.94897, 5.69867) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(0.861603, -0.507583, 0, 0.507583, 0.861603, 0, 0, 0, 1, 1.68174, 0.365051, 12.4396) +operation = 2 +size = Vector3(5.18265, 4.66061, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(0.956661, -0.291203, 0, 0.291203, 0.956661, 0, 8.9407e-08, -7.45058e-09, 1, -5.16157, 2.49941, 12.5804) +operation = 2 +size = Vector3(8.79707, 4.04699, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D11" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(-1.49012e-07, 6.70552e-08, -1, 0.291203, 0.956661, 0, 0.956661, -0.291203, -5.96046e-08, -10.3324, 0.55706, 9.10962) +operation = 2 +size = Vector3(8.30031, 5.37523, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(0.942027, 0.335534, 0, -0.335534, 0.942028, 0, 2.38419e-07, 7.45058e-08, 1, 1.96285, 0.912893, -11.3267) +operation = 2 +size = Vector3(20.6193, 10.1297, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(2.98023e-07, -2.98023e-08, 1, 0.477634, 0.878559, 0, -0.878558, 0.477634, 0, -11.4397, 0.843881, -2.17569) +operation = 2 +size = Vector3(9.11396, 5.37523, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +transform = Transform3D(1.19209e-07, -4.47035e-08, 1, 0.22165, 0.975126, 0, -0.975125, 0.22165, 0, -11.4397, -1.17258, -1.42908) +operation = 2 +size = Vector3(9.26142, 5.37523, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(-0.980662, 0, -0.195706, 0, 1, 0, 0.195706, 0, -0.980662, 16.4482, 1.24028, 10.8159) +size = Vector3(22.6908, 2.53036, 26.0577) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +operation = 2 +size = Vector3(21.699, 4.94897, 24.7637) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) +operation = 2 +size = Vector3(5.48248, 4.94897, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D11" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, 9.81546, 1.02972, -11.1309) +operation = 2 +size = Vector3(5.48248, 2.88953, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D12" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(0.968409, -0.249366, -7.45058e-08, 0.249366, 0.968409, 0, 7.21521e-08, -1.85792e-08, 1, 7.47525, 1.68203, -11.1309) +operation = 2 +size = Vector3(5.48248, 2.88953, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, -7.5132, 2.28486, -10.4518) +operation = 2 +size = Vector3(8.62306, 4.94897, 5.58841) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(0.920047, -0.391807, -7.45058e-08, 0.391807, 0.920047, 0, 7.45058e-08, -2.98023e-08, 1, -6.59657, 0.52667, -12.3894) +operation = 2 +size = Vector3(7.21283, 3.23804, 1.71315) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, -1.74361, 1.34271, 10.7097) +operation = 2 +size = Vector3(19.7208, 2.26355, 5.36632) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(0.90949, -0.415725, -7.45058e-08, 0.415725, 0.90949, 0, 5.96046e-08, -2.98023e-08, 1, 6.5508, 1.03969, 12.4855) +operation = 2 +size = Vector3(3.29733, 2.26355, 1.9962) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +transform = Transform3D(0.872811, 0.488058, -7.45058e-08, -0.488058, 0.872811, 0, 5.96046e-08, 4.47035e-08, 1, 3.25758, 0.0104947, 12.4855) +operation = 2 +size = Vector3(3.29733, 3.41986, 1.9962) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.4648, 1.24028, -35.2034) +size = Vector3(22.6908, 2.53036, 26.0577) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +operation = 2 +size = Vector3(21.699, 4.94897, 24.7637) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) +operation = 2 +size = Vector3(5.48248, 4.94897, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +transform = Transform3D(0.922282, -0.386518, 0, 0.386518, 0.922282, 0, 0, 0, 1, -1.86533, 0.1865, 12.965) +operation = 2 +size = Vector3(7.06031, 5.05847, 2.48825) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +transform = Transform3D(-4.03142e-08, 1.68952e-08, 1, 0.386518, 0.922282, 0, -0.922282, 0.386518, -4.37114e-08, -10.9717, 0.1865, -0.139679) +operation = 2 +size = Vector3(7.06031, 5.05847, 2.48825) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +transform = Transform3D(-0.999949, 0.0101053, -8.74228e-08, 0.0101053, 0.999949, 0, 8.74183e-08, -8.83436e-10, -1, 1.46112, -0.431518, -12.5492) +operation = 2 +size = Vector3(10.2582, 5.05847, 2.48825) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +transform = Transform3D(1, 0, 0, 0, 0.856465, 0.516204, 0, -0.516204, 0.856465, 11.0115, 0, -6.14323) +operation = 2 +size = Vector3(3.41214, 4.94897, 4.52136) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0259626, -3.00393, -0.963224) +size = Vector3(86.0781, 6, 106.223) +material = ExtResource("1_etye1") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.295873, -0.0920334, -20.6882) +size = Vector3(5.66602, 0.212601, 66.5905) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(0.951525, 0, 0.307573, 0, 1, 0, -0.307573, 0, 0.951525, 6.34913, -0.0920353, 30.9568) +size = Vector3(5.66602, 0.212601, 40.6149) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld"] +transform = Transform3D(0.979392, 0, 0.201967, 0, 1, 0, -0.201967, 0, 0.979392, 2.65383, -0.0920353, 13.0373) +size = Vector3(5.66602, 0.212601, 22.0021) +material = ExtResource("1_sb1vi") + +[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.7127, -3.8147e-06, -4.44497) +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) +size = Vector3(13.2101, 6.39868, 18.7856) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) +operation = 2 +size = Vector3(12.1248, 7.93005, 17.5173) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.50422, 4.57072, -8.66012) +operation = 2 +size = Vector3(2.34985, 3.30096, 3.98828) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) +operation = 2 +size = Vector3(1.52942, 1.75981, 1.18262) +material = ExtResource("1_sb1vi") + +[node name="CSGCombiner3D5" type="CSGCombiner3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.3902, -3.8147e-06, -34.9045) +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) +size = Vector3(13.2101, 6.39868, 18.7856) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) +operation = 2 +size = Vector3(12.1248, 7.93005, 17.5173) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.44811, 4.70709, -8.66012) +operation = 2 +size = Vector3(2.34985, 3.30096, 4.2832) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D5"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) +operation = 2 +size = Vector3(1.52942, 1.75981, 1.18262) +material = ExtResource("1_sb1vi") + +[node name="CSGCombiner3D2" type="CSGCombiner3D" parent="."] +transform = Transform3D(0.947261, 0, 0.320464, 0, 1, 0, -0.320464, 0, 0.947261, -9.09123, 0, 34.072) +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) +size = Vector3(13.2101, 6.39868, 18.7856) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) +operation = 2 +size = Vector3(12.1248, 7.93005, 17.5173) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(-2.98023e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -2.98023e-08, -6.70552e-08, 1.43882, 4.72967, -8.66012) +operation = 2 +size = Vector3(2.34985, 3.30096, 4.33203) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) +operation = 2 +size = Vector3(1.52942, 1.75981, 1.18262) +material = ExtResource("1_sb1vi") + +[node name="CSGCombiner3D3" type="CSGCombiner3D" parent="."] +transform = Transform3D(-0.979862, 0, -0.199676, 0, 1, 0, 0.199676, 0, -0.979862, 18.4676, 0, 11.5749) +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) +size = Vector3(13.2101, 6.39868, 18.7856) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) +operation = 2 +size = Vector3(12.1248, 7.93005, 17.5173) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.55623, 4.44428, -8.66012) +operation = 2 +size = Vector3(2.34985, 3.30096, 3.71484) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) +operation = 2 +size = Vector3(1.52942, 1.75981, 1.18262) +material = ExtResource("1_sb1vi") + +[node name="CSGCombiner3D4" type="CSGCombiner3D" parent="."] +transform = Transform3D(-0.970654, 0, 0.240482, 0, 1, 0, -0.240482, 0, -0.970654, 19.1359, 0, -21.0191) +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) +size = Vector3(13.2101, 6.39868, 18.7856) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) +operation = 2 +size = Vector3(12.1248, 7.93005, 17.5173) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) +operation = 2 +size = Vector3(6.36378, 4.64685, 18.8601) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) +operation = 2 +size = Vector3(2.34985, 3.30096, 4) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.55623, 4.44428, -8.66012) +operation = 2 +size = Vector3(2.34985, 3.30096, 3.71484) +material = ExtResource("1_sb1vi") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D4"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) +operation = 2 +size = Vector3(1.52942, 1.75981, 1.18262) +material = ExtResource("1_sb1vi") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(-0.882496, -0.0801336, 0.463442, -1.11759e-08, 0.985378, 0.170381, -0.470319, 0.150361, -0.869593, 13.939, 2.24424, -48.4686) +fov = 50.625 diff --git a/project/maps/map.tscn b/project/maps/map.tscn new file mode 100644 index 00000000..1b3b8ddb --- /dev/null +++ b/project/maps/map.tscn @@ -0,0 +1,126 @@ +[gd_scene load_steps=11 format=3 uid="uid://mn086drdvyym"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_oejri"] +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_urvl1"] +sky_material = SubResource("ProceduralSkyMaterial_oejri") + +[sub_resource type="Environment" id="Environment_ers5l"] +background_mode = 2 +sky = SubResource("Sky_urvl1") +tonemap_mode = 2 +glow_enabled = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_oejri"] +albedo_color = Color(0.16206, 0.18, 0.1332, 1) + +[sub_resource type="QuadMesh" id="QuadMesh_oejri"] +size = Vector2(100, 100) +orientation = 1 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_urvl1"] +albedo_color = Color(0.21, 0.232, 0.25, 1) + +[sub_resource type="CylinderMesh" id="CylinderMesh_ers5l"] +top_radius = 10.0 +bottom_radius = 10.0 +height = 0.5 + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_c3pkw"] +radius = 2.86377 + +[sub_resource type="PrismMesh" id="PrismMesh_oejri"] + +[sub_resource type="BoxMesh" id="BoxMesh_oejri"] +size = Vector3(0.53, 0.56, 1) + +[node name="Map" type="Node3D"] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_ers5l") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) +shadow_enabled = true + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +material_override = SubResource("StandardMaterial3D_oejri") +mesh = SubResource("QuadMesh_oejri") + +[node name="LocaleMarker" type="LocaleMarker" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 19.8126, -1.90735e-06, -10.5129) +locale_scene = "uid://bqaoxvqgrbi3v" +entrance_path = "%CampEntrance" + +[node name="MeshInstance3D" type="MeshInstance3D" parent="LocaleMarker"] +material_override = SubResource("StandardMaterial3D_urvl1") +mesh = SubResource("CylinderMesh_ers5l") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="LocaleMarker"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1601, 0, 4.78461) +shape = SubResource("CylinderShape3D_c3pkw") + +[node name="Label3D" type="Label3D" parent="LocaleMarker"] +transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, 0, 1.03264, 0) +pixel_size = 0.1 +text = "City +" + +[node name="Label3D2" type="Label3D" parent="LocaleMarker"] +transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, -14.3197, 1.03264, 2.5534) +pixel_size = 0.05 +text = "Camp" + +[node name="Label3D3" type="Label3D" parent="LocaleMarker"] +transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, -15.5085, 1.03264, 4.74225) +pixel_size = 0.05 +modulate = Color(1, 0, 0, 1) +text = "! +" + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -15.7257, 0, 5.36808) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -15.7232, 0, 4.67118) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D4" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -15.807, 0, 4.03467) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D5" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.7496, -4.76837e-07, 2.95756) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D6" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.2813, -4.76837e-07, 3.76329) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D7" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.2956, -4.76837e-07, 4.4297) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D8" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.3204, -4.76837e-07, 5.30799) +mesh = SubResource("PrismMesh_oejri") + +[node name="MeshInstance3D9" type="MeshInstance3D" parent="LocaleMarker"] +transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.3516, -4.76837e-07, 6.29061) +mesh = SubResource("PrismMesh_oejri") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.258819, 0.965926, 0, -0.965926, 0.258819, 0, 26.4443, 6.29706) +fov = 52.6 + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.292486, 0) +mesh = SubResource("BoxMesh_oejri") + +[node name="Label3D" type="Label3D" parent="MeshInstance3D2"] +transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, 0, 1.03264, -0.956246) +pixel_size = 0.05 +text = "You" diff --git a/project/materials/grids/bricks.tres b/project/materials/grids/bricks.tres new file mode 100644 index 00000000..1911e356 --- /dev/null +++ b/project/materials/grids/bricks.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://ke4yek3xtin5"] + +[ext_resource type="Texture2D" uid="uid://cd4cchmulwnc5" path="res://textures/grids/bricks.png" id="1_ustix"] + +[resource] +albedo_texture = ExtResource("1_ustix") +uv1_triplanar = true diff --git a/project/materials/grids/grass.tres b/project/materials/grids/grass.tres new file mode 100644 index 00000000..ebb67f75 --- /dev/null +++ b/project/materials/grids/grass.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://cbuk8uxxuj7j5"] + +[ext_resource type="Texture2D" uid="uid://f8djywm2jlah" path="res://textures/grids/grass.png" id="1_lqti4"] + +[resource] +albedo_texture = ExtResource("1_lqti4") +uv1_triplanar = true diff --git a/project/materials/grids/mud.tres b/project/materials/grids/mud.tres new file mode 100644 index 00000000..6b69d38e --- /dev/null +++ b/project/materials/grids/mud.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://blcccgo88gl7c"] + +[ext_resource type="Texture2D" uid="uid://br64q04tpxmli" path="res://textures/grids/mud.png" id="1_kexk5"] + +[resource] +albedo_texture = ExtResource("1_kexk5") +uv1_triplanar = true diff --git a/project/materials/grids/tent.tres b/project/materials/grids/tent.tres new file mode 100644 index 00000000..6f791f11 --- /dev/null +++ b/project/materials/grids/tent.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://cupy5mpdsngcl"] + +[ext_resource type="Texture2D" uid="uid://bh68a5vqm5h7l" path="res://textures/grids/tent.png" id="1_ifivq"] + +[resource] +albedo_texture = ExtResource("1_ifivq") +uv1_triplanar = true diff --git a/project/project.godot b/project/project.godot index 8cd51d29..e0cf7709 100644 --- a/project/project.godot +++ b/project/project.godot @@ -11,5 +11,6 @@ config_version=5 [application] config/name="authority" +run/main_scene="uid://mn086drdvyym" config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://icon.svg" diff --git a/project/textures/grids/bricks.png b/project/textures/grids/bricks.png new file mode 100644 index 0000000000000000000000000000000000000000..788d510e09759d8de897d3a0ad23e5263bc24082 GIT binary patch literal 18043 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 Mp00i_>zopr0Q0Aq%K!iX literal 0 HcmV?d00001 diff --git a/project/textures/grids/grass.png.import b/project/textures/grids/grass.png.import new file mode 100644 index 00000000..10e02de2 --- /dev/null +++ b/project/textures/grids/grass.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://f8djywm2jlah" +path.s3tc="res://.godot/imported/grass.png-94a6319b2d9ea30e834183f2653f3455.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/grids/grass.png" +dest_files=["res://.godot/imported/grass.png-94a6319b2d9ea30e834183f2653f3455.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/project/textures/grids/mud.png b/project/textures/grids/mud.png new file mode 100644 index 0000000000000000000000000000000000000000..529ceab829292e8651fc121cfa9fb8c740f0a042 GIT binary patch literal 15859 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 kB!k-J0?@|E1iOFruKWoz1poj5 literal 0 HcmV?d00001 diff --git a/project/textures/grids/mud.png.import b/project/textures/grids/mud.png.import new file mode 100644 index 00000000..7a14f648 --- /dev/null +++ b/project/textures/grids/mud.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://br64q04tpxmli" +path.s3tc="res://.godot/imported/mud.png-f0a13a766854ada7e9976a2898dea1c2.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/grids/mud.png" +dest_files=["res://.godot/imported/mud.png-f0a13a766854ada7e9976a2898dea1c2.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/project/textures/grids/rock.png b/project/textures/grids/rock.png new file mode 100644 index 0000000000000000000000000000000000000000..3380a55a32a30da7be22acf1ab322dc6009e398f GIT binary patch literal 16603 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 bSJ3)XFY|QsT-mP^?}GTAu6{1-oD!M Date: Fri, 27 Jun 2025 00:54:15 +0200 Subject: [PATCH 6/8] feat: started work on actors and party members --- modules/authority/actor_body.cpp | 68 ++++++ modules/authority/actor_body.h | 34 +++ modules/authority/game_state.cpp | 22 ++ modules/authority/game_state.h | 6 +- modules/authority/party_member_data.cpp | 36 +++ modules/authority/party_member_data.h | 26 +++ modules/authority/player_actor.cpp | 27 +++ modules/authority/player_actor.h | 16 ++ modules/authority/player_input.cpp | 72 ++++++ modules/authority/player_input.h | 33 +++ modules/authority/register_types.cpp | 10 +- project/locales/city.tscn | 224 ++++++++++--------- project/maps/map.tscn | 2 +- project/objects/characters/player_actor.tscn | 21 ++ project/project.godot | 23 ++ 15 files changed, 513 insertions(+), 107 deletions(-) create mode 100644 modules/authority/actor_body.cpp create mode 100644 modules/authority/actor_body.h create mode 100644 modules/authority/party_member_data.cpp create mode 100644 modules/authority/party_member_data.h create mode 100644 modules/authority/player_actor.cpp create mode 100644 modules/authority/player_actor.h create mode 100644 modules/authority/player_input.cpp create mode 100644 modules/authority/player_input.h create mode 100644 project/objects/characters/player_actor.tscn diff --git a/modules/authority/actor_body.cpp b/modules/authority/actor_body.cpp new file mode 100644 index 00000000..e2937295 --- /dev/null +++ b/modules/authority/actor_body.cpp @@ -0,0 +1,68 @@ +#include "actor_body.h" +#include "core/config/engine.h" +#include "core/object/object.h" +#include "macros.h" + +void ActorBody::_bind_methods() { + BIND_HPROPERTY(Variant::FLOAT, movement_speed, PROPERTY_HINT_RANGE, "0.0,20.0"); +} + +void ActorBody::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_PHYSICS_PROCESS: + physics_process(get_physics_process_delta_time()); + return; + } +} + +void ActorBody::physics_process(double delta) { + set_velocity(get_movement_direction() * this->movement_speed); + move_and_slide(); +} + +void ActorBody::set_movement_direction(Vector3 direction) { + this->mode = Direction; + this->movement_vector = { direction.x, 0.f, direction.y }; +} + +Vector3 ActorBody::get_movement_direction() const { + switch (this->mode) { + case Position: { + Vector3 const direction_3d{ get_global_position().direction_to(get_movement_target()) }; + return Vector3{ direction_3d.x, 0.f, direction_3d.z }; + } break; + case Direction: + return this->movement_vector; + } +} + +void ActorBody::set_movement_target(Vector3 location) { + this->mode = Position; + this->movement_vector = { location.x, 0.f, location.y }; +} + +Vector3 ActorBody::get_movement_target() const { + switch (this->mode) { + case Position: + return this->movement_vector; + case Direction: + return get_global_position() + this->movement_vector; + } +} + +void ActorBody::set_movement_speed(float speed) { + this->movement_speed = speed; +} + +float ActorBody::get_movement_speed() const { + return this->movement_speed; +} + +ActorBody::MovementMode ActorBody::get_movement_mode() const { + return this->mode; +} diff --git a/modules/authority/actor_body.h b/modules/authority/actor_body.h new file mode 100644 index 00000000..5fb20086 --- /dev/null +++ b/modules/authority/actor_body.h @@ -0,0 +1,34 @@ +#ifndef ACTOR_BODY_H +#define ACTOR_BODY_H + +#include "scene/3d/physics/character_body_3d.h" + +class ActorBody : public CharacterBody3D { + GDCLASS(ActorBody, CharacterBody3D); + static void _bind_methods(); + void physics_process(double delta); + +public: + // support both directional and positional movement modes + enum MovementMode { + Direction, + Position + }; + void _notification(int what); + + void set_movement_direction(Vector3 direction); + Vector3 get_movement_direction() const; + void set_movement_target(Vector3 location); + Vector3 get_movement_target() const; + + void set_movement_speed(float speed); + float get_movement_speed() const; + MovementMode get_movement_mode() const; + +private: + float movement_speed{ 1.f }; + Vector3 movement_vector{ 0.f, 0.f, 0.f }; + MovementMode mode{ Direction }; +}; + +#endif //! ACTOR_BODY_H diff --git a/modules/authority/game_state.cpp b/modules/authority/game_state.cpp index 026b13eb..e3a2e0f1 100644 --- a/modules/authority/game_state.cpp +++ b/modules/authority/game_state.cpp @@ -6,6 +6,10 @@ GameState *GameState::singleton_instance{ nullptr }; void GameState::_bind_methods() { BIND_PROPERTY(Variant::STRING, locale_uid); BIND_PROPERTY(Variant::STRING, locale_entrance_path); + { + String const party_member_data_hint{ vformat("%s/%s:PartyMemberData", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE) }; + BIND_HPROPERTY(Variant::ARRAY, player_party, PROPERTY_HINT_ARRAY_TYPE, party_member_data_hint); + } } GameState::GameState() { @@ -35,3 +39,21 @@ void GameState::set_locale_entrance_path(String const &value) { String GameState::get_locale_entrance_path() const { return this->locale_uid; } + +void GameState::set_player_party(Array array) { + this->player_party.clear(); + for (int i{ 0 }; i < array.size(); ++i) { + Ref data{ array[i] }; + if (data.is_valid()) { + this->player_party.push_back(data); + } + } +} + +Array GameState::get_player_party() const { + Array a{}; + for (Ref const &data : this->player_party) { + a.push_back(data); + } + return a; +} diff --git a/modules/authority/game_state.h b/modules/authority/game_state.h index a818357d..b3f0a7af 100644 --- a/modules/authority/game_state.h +++ b/modules/authority/game_state.h @@ -1,8 +1,9 @@ #ifndef GAME_STATE_H #define GAME_STATE_H -#include "core/object/class_db.h" +#include "authority/party_member_data.h" #include "core/object/object.h" +#include "core/templates/vector.h" class GameState : public Object { GDCLASS(GameState, Object); @@ -17,10 +18,13 @@ public: String get_locale_uid() const; void set_locale_entrance_path(String const &value); String get_locale_entrance_path() const; + void set_player_party(Array array); + Array get_player_party() const; private: String locale_uid{ "" }; String locale_entrance_path{ "" }; + Vector> player_party{}; }; #endif // !GAME_STATE_H diff --git a/modules/authority/party_member_data.cpp b/modules/authority/party_member_data.cpp new file mode 100644 index 00000000..46d95c8f --- /dev/null +++ b/modules/authority/party_member_data.cpp @@ -0,0 +1,36 @@ +#include "party_member_data.h" +#include "macros.h" + +void PartyMemberData::_bind_methods() { + BIND_PROPERTY(Variant::STRING, first_name); + BIND_PROPERTY(Variant::INT, player_trust); + BIND_PROPERTY(Variant::INT, player_fear); +} + +int PartyMemberData::get_player_authority() const { + return this->player_fear + this->player_trust; +} + +void PartyMemberData::set_first_name(String name) { + this->first_name = name; +} + +String PartyMemberData::get_first_name() const { + return this->first_name; +} + +void PartyMemberData::set_player_trust(int value) { + this->player_trust = value; +} + +int PartyMemberData::get_player_trust() const { + return this->player_trust; +} + +void PartyMemberData::set_player_fear(int value) { + this->player_fear = value; +} + +int PartyMemberData::get_player_fear() const { + return this->player_fear; +} diff --git a/modules/authority/party_member_data.h b/modules/authority/party_member_data.h new file mode 100644 index 00000000..91c9a5c1 --- /dev/null +++ b/modules/authority/party_member_data.h @@ -0,0 +1,26 @@ +#ifndef PARTY_MEMBER_DATA_H +#define PARTY_MEMBER_DATA_H + +#include "core/io/resource.h" + +class PartyMemberData : public Resource { + GDCLASS(PartyMemberData, Resource); + static void _bind_methods(); + +public: + int get_player_authority() const; + + void set_first_name(String name); + String get_first_name() const; + void set_player_trust(int value); + int get_player_trust() const; + void set_player_fear(int value); + int get_player_fear() const; + +private: + String first_name{ "Firstname" }; + int player_trust{ 1 }; + int player_fear{ 1 }; +}; + +#endif // !PARTY_MEMBER_DATA_H diff --git a/modules/authority/player_actor.cpp b/modules/authority/player_actor.cpp new file mode 100644 index 00000000..5bc08134 --- /dev/null +++ b/modules/authority/player_actor.cpp @@ -0,0 +1,27 @@ +#include "player_actor.h" +#include "authority/player_input.h" + +void PlayerActor::_bind_methods() { +} + +void PlayerActor::ready() { + PlayerInput *input{ cast_to(get_node(NodePath("%PlayerInput"))) }; + input->connect(PlayerInput::signal_movement, callable_mp(this, &self_type::input_move)); +} + +void PlayerActor::input_move(Vector2 movement) { + set_movement_direction({ movement.x, 0.f, movement.y }); +} + +void PlayerActor::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_READY: + ready(); + return; + } +} diff --git a/modules/authority/player_actor.h b/modules/authority/player_actor.h new file mode 100644 index 00000000..af7bd862 --- /dev/null +++ b/modules/authority/player_actor.h @@ -0,0 +1,16 @@ +#ifndef PLAYER_ACTOR_H +#define PLAYER_ACTOR_H + +#include "actor_body.h" + +class PlayerActor : public ActorBody { + GDCLASS(PlayerActor, ActorBody); + static void _bind_methods(); + void ready(); + void input_move(Vector2 movement); + +public: + void _notification(int what); +}; + +#endif // !PLAYER_ACTOR_H diff --git a/modules/authority/player_input.cpp b/modules/authority/player_input.cpp new file mode 100644 index 00000000..4228c55d --- /dev/null +++ b/modules/authority/player_input.cpp @@ -0,0 +1,72 @@ +#include "player_input.h" + +#include "core/input/input_event.h" +#include "macros.h" + +String const PlayerInput::signal_movement{ "movement" }; + +void PlayerInput::_bind_methods() { + BIND_PROPERTY(Variant::STRING, action_move_left); + BIND_PROPERTY(Variant::STRING, action_move_right); + BIND_PROPERTY(Variant::STRING, action_move_forward); + BIND_PROPERTY(Variant::STRING, action_move_back); + ADD_SIGNAL(MethodInfo(self_type::signal_movement, PropertyInfo(Variant::VECTOR2, "movement_directions"))); +} + +void PlayerInput::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_READY: + this->set_process_unhandled_input(true); + return; + } +} + +void PlayerInput::unhandled_input(Ref const &event) { + Input *input{ Input::get_singleton() }; + bool is_movement_action{ event->is_action(self_type::action_move_left) }; + is_movement_action |= event->is_action(self_type::action_move_right); + is_movement_action |= event->is_action(self_type::action_move_forward); + is_movement_action |= event->is_action(self_type::action_move_back); + if (is_movement_action) { + float const h_axis{ input->get_axis(self_type::action_move_right, self_type::action_move_left) }; + float const v_axis{ input->get_axis(self_type::action_move_back, self_type::action_move_forward) }; + this->emit_signal(self_type::signal_movement, Vector2{ h_axis, v_axis }); + } +} + +void PlayerInput::set_action_move_left(String action) { + this->action_move_left = action; +} + +String PlayerInput::get_action_move_left() const { + return this->action_move_left; +} + +void PlayerInput::set_action_move_right(String action) { + this->action_move_right = action; +} + +String PlayerInput::get_action_move_right() const { + return this->action_move_right; +} + +void PlayerInput::set_action_move_forward(String action) { + this->action_move_forward = action; +} + +String PlayerInput::get_action_move_forward() const { + return this->action_move_forward; +} + +void PlayerInput::set_action_move_back(String action) { + this->action_move_back = action; +} + +String PlayerInput::get_action_move_back() const { + return this->action_move_back; +} diff --git a/modules/authority/player_input.h b/modules/authority/player_input.h new file mode 100644 index 00000000..7dba0ec4 --- /dev/null +++ b/modules/authority/player_input.h @@ -0,0 +1,33 @@ +#ifndef PLAYER_INPUT_H +#define PLAYER_INPUT_H + +#include "core/input/input_event.h" +#include "scene/main/node.h" + +class PlayerInput : public Node { + GDCLASS(PlayerInput, Node); + static void _bind_methods(); + +public: + void _notification(int what); + virtual void unhandled_input(Ref const &event) override; + void set_action_move_left(String action); + String get_action_move_left() const; + void set_action_move_right(String action); + String get_action_move_right() const; + void set_action_move_forward(String action); + String get_action_move_forward() const; + void set_action_move_back(String action); + String get_action_move_back() const; + +public: + static String const signal_movement; + +private: + String action_move_left{ "move_left" }; + String action_move_right{ "move_right" }; + String action_move_forward{ "move_forward" }; + String action_move_back{ "move_back" }; +}; + +#endif // !PLAYER_INPUT_H diff --git a/modules/authority/register_types.cpp b/modules/authority/register_types.cpp index 4d0c421a..0d44b7d7 100644 --- a/modules/authority/register_types.cpp +++ b/modules/authority/register_types.cpp @@ -1,7 +1,11 @@ #include "register_types.h" +#include "authority/actor_body.h" #include "authority/game_state.h" #include "authority/locale_marker.h" +#include "authority/party_member_data.h" +#include "authority/player_actor.h" +#include "authority/player_input.h" #include "core/config/engine.h" #include "core/object/class_db.h" @@ -12,7 +16,11 @@ void initialize_authority_module(ModuleInitializationLevel p_level) { return; } GDREGISTER_CLASS(GameState); - GDREGISTER_CLASS(LocaleMarker); + GDREGISTER_RUNTIME_CLASS(LocaleMarker); + GDREGISTER_RUNTIME_CLASS(PartyMemberData); + GDREGISTER_CLASS(ActorBody); + GDREGISTER_CLASS(PlayerActor); + GDREGISTER_CLASS(PlayerInput); game_state = memnew(GameState); Engine::get_singleton()->add_singleton(Engine::Singleton("GameState", GameState::get_singleton())); diff --git a/project/locales/city.tscn b/project/locales/city.tscn index 2e304ffc..45461d8d 100644 --- a/project/locales/city.tscn +++ b/project/locales/city.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=6 format=3 uid="uid://bqaoxvqgrbi3v"] +[gd_scene load_steps=7 format=3 uid="uid://bqaoxvqgrbi3v"] [ext_resource type="Material" uid="uid://cbuk8uxxuj7j5" path="res://materials/grids/grass.tres" id="1_etye1"] [ext_resource type="Material" uid="uid://ke4yek3xtin5" path="res://materials/grids/bricks.tres" id="1_sb1vi"] +[ext_resource type="PackedScene" uid="uid://cykd1a23ria6k" path="res://objects/characters/player_actor.tscn" id="3_vuk2b"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_sb1vi"] sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) @@ -16,559 +17,574 @@ sky = SubResource("Sky_vuk2b") tonemap_mode = 2 glow_enabled = true -[node name="City" type="Node3D"] +[node name="City" type="Node"] -[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +[node name="PartySelectionUI" type="CanvasLayer" parent="."] + +[node name="VBoxContainer" type="VBoxContainer" parent="PartySelectionUI"] +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = -298.0 +offset_top = -211.0 +offset_bottom = 211.0 +grow_horizontal = 0 +grow_vertical = 2 + +[node name="Level" type="Node3D" parent="."] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="Level"] environment = SubResource("Environment_wwygw") -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] -transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Level"] +transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0) shadow_enabled = true -[node name="CSGWorld" type="CSGCombiner3D" parent="."] +[node name="CSGWorld" type="CSGCombiner3D" parent="Level"] use_collision = true -[node name="CSGBox3D2" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.7726, 1.24028, -3.26613) size = Vector3(29.3063, 2.53036, 32.2042) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] operation = 2 size = Vector3(28.3818, 4.94897, 31.2627) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.3707, 0, 8.21931) operation = 2 size = Vector3(5.48248, 4.94897, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(0.996095, -0.0882858, 0, 0.0882858, 0.996095, 0, 0, 0, 1, -4.27235, 1.64007, -16.0551) operation = 2 size = Vector3(17.209, 2.77515, 1.67773) material = ExtResource("1_sb1vi") -[node name="CSGBox3D11" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D11" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(-0.662908, 0.748701, 0, -0.748701, -0.662908, 0, 0, 0, 1, 1.99536, 0.140041, -16.0551) operation = 2 size = Vector3(3.51099, 4.26892, 1.67773) material = ExtResource("1_sb1vi") -[node name="CSGBox3D12" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D12" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(0.0515306, -0.596407, 0.801026, -0.589269, -0.665739, -0.45777, 0.806292, -0.448431, -0.38575, 13.6247, 0.402275, -15.0203) operation = 2 size = Vector3(4.65393, 4.26892, 4.29919) material = ExtResource("1_sb1vi") -[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(1, 0, 0, 0, 0.990234, 0.139415, 0, -0.139415, 0.990234, -15.0347, 1.84148, -10.1624) operation = 2 size = Vector3(5.48248, 4.94897, 15.628) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(0.996356, 0.0852952, 0, -0.0852952, 0.996356, 0, 0, 0, 1, -6.08641, 2.3849, 15.0748) operation = 2 size = Vector3(18.0761, 4.49255, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D13" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D13" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(0.940934, 0.33859, 0, -0.33859, 0.940934, 0, 0, 0, 1, 10.9771, 1.22338, 15.0748) operation = 2 size = Vector3(5.48767, 4.49255, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(0.998184, -0.0602297, 0, 0.0602297, 0.998184, 0, 0, 0, 1, -11.169, 1.83497, 16.5285) operation = 2 size = Vector3(7.92215, 4.49255, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D2"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] transform = Transform3D(0.938076, -0.346428, 0, 0.346428, 0.938076, 0, 0, 0, 1, -8.1568, 0.67643, 16.5285) operation = 2 size = Vector3(4.54713, 4.49255, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 17.3635, 1.24027, -22.297) size = Vector3(29.3063, 2.53036, 32.2042) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] operation = 2 size = Vector3(28.3818, 4.94897, 31.2627) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.3707, 0, 8.21931) operation = 2 size = Vector3(5.48248, 4.94897, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.67738, 1.90735e-06, -15.8587) operation = 2 size = Vector3(11.8087, 4.94897, 1.39062) material = ExtResource("1_sb1vi") -[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] transform = Transform3D(0.983341, 0.181772, 0, -0.181772, 0.983341, 0, 0, 0, 1, 5.71055, 0.339279, 15.5698) operation = 2 size = Vector3(9.78, 4.23425, 1.39062) material = ExtResource("1_sb1vi") -[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -14.4351, 1.90735e-06, -3.8005) operation = 2 size = Vector3(11.8087, 4.94897, 1.39062) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] transform = Transform3D(0.835299, 0.549796, 0, -0.549796, 0.835299, 0, 0, 0, 1, -2.58652, 1.00152, -15.8587) operation = 2 size = Vector3(2.53568, 4.46423, 1.39062) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D9"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] transform = Transform3D(0.835299, 0.549796, -9.2008e-09, -0.491933, 0.747388, 0.446557, 0.245515, -0.373009, 0.894755, -14.5944, -0.54182, -15.1699) operation = 2 size = Vector3(3, 4.46423, 2.88232) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(0.94881, 0, 0.315848, 0, 1, 0, -0.315848, 0, 0.94881, -7.66859, 1.24028, 32.2569) size = Vector3(22.6908, 2.53036, 26.0577) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] operation = 2 size = Vector3(21.699, 4.94897, 24.7637) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) operation = 2 size = Vector3(5.48248, 4.94897, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D12" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D12" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(0.966641, 0.256107, 0.00379327, -0.221096, 0.841791, -0.492448, -0.129312, 0.475181, 0.870333, 10.1198, 1.29747, 12.165) operation = 2 size = Vector3(5.48248, 4.94897, 5.69867) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(0.861603, -0.507583, 0, 0.507583, 0.861603, 0, 0, 0, 1, 1.68174, 0.365051, 12.4396) operation = 2 size = Vector3(5.18265, 4.66061, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(0.956661, -0.291203, 0, 0.291203, 0.956661, 0, 8.9407e-08, -7.45058e-09, 1, -5.16157, 2.49941, 12.5804) operation = 2 size = Vector3(8.79707, 4.04699, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D11" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D11" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(-1.49012e-07, 6.70552e-08, -1, 0.291203, 0.956661, 0, 0.956661, -0.291203, -5.96046e-08, -10.3324, 0.55706, 9.10962) operation = 2 size = Vector3(8.30031, 5.37523, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(0.942027, 0.335534, 0, -0.335534, 0.942028, 0, 2.38419e-07, 7.45058e-08, 1, 1.96285, 0.912893, -11.3267) operation = 2 size = Vector3(20.6193, 10.1297, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(2.98023e-07, -2.98023e-08, 1, 0.477634, 0.878559, 0, -0.878558, 0.477634, 0, -11.4397, 0.843881, -2.17569) operation = 2 size = Vector3(9.11396, 5.37523, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D4"] +[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] transform = Transform3D(1.19209e-07, -4.47035e-08, 1, 0.22165, 0.975126, 0, -0.975125, 0.22165, 0, -11.4397, -1.17258, -1.42908) operation = 2 size = Vector3(9.26142, 5.37523, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(-0.980662, 0, -0.195706, 0, 1, 0, 0.195706, 0, -0.980662, 16.4482, 1.24028, 10.8159) size = Vector3(22.6908, 2.53036, 26.0577) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] operation = 2 size = Vector3(21.699, 4.94897, 24.7637) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) operation = 2 size = Vector3(5.48248, 4.94897, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D11" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D11" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, 9.81546, 1.02972, -11.1309) operation = 2 size = Vector3(5.48248, 2.88953, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D12" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D12" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(0.968409, -0.249366, -7.45058e-08, 0.249366, 0.968409, 0, 7.21521e-08, -1.85792e-08, 1, 7.47525, 1.68203, -11.1309) operation = 2 size = Vector3(5.48248, 2.88953, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, -7.5132, 2.28486, -10.4518) operation = 2 size = Vector3(8.62306, 4.94897, 5.58841) material = ExtResource("1_sb1vi") -[node name="CSGBox3D10" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(0.920047, -0.391807, -7.45058e-08, 0.391807, 0.920047, 0, 7.45058e-08, -2.98023e-08, 1, -6.59657, 0.52667, -12.3894) operation = 2 size = Vector3(7.21283, 3.23804, 1.71315) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, -1.74361, 1.34271, 10.7097) operation = 2 size = Vector3(19.7208, 2.26355, 5.36632) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(0.90949, -0.415725, -7.45058e-08, 0.415725, 0.90949, 0, 5.96046e-08, -2.98023e-08, 1, 6.5508, 1.03969, 12.4855) operation = 2 size = Vector3(3.29733, 2.26355, 1.9962) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D7"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] transform = Transform3D(0.872811, 0.488058, -7.45058e-08, -0.488058, 0.872811, 0, 5.96046e-08, 4.47035e-08, 1, 3.25758, 0.0104947, 12.4855) operation = 2 size = Vector3(3.29733, 3.41986, 1.9962) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.4648, 1.24028, -35.2034) size = Vector3(22.6908, 2.53036, 26.0577) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] operation = 2 size = Vector3(21.699, 4.94897, 24.7637) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) operation = 2 size = Vector3(5.48248, 4.94897, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] transform = Transform3D(0.922282, -0.386518, 0, 0.386518, 0.922282, 0, 0, 0, 1, -1.86533, 0.1865, 12.965) operation = 2 size = Vector3(7.06031, 5.05847, 2.48825) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] transform = Transform3D(-4.03142e-08, 1.68952e-08, 1, 0.386518, 0.922282, 0, -0.922282, 0.386518, -4.37114e-08, -10.9717, 0.1865, -0.139679) operation = 2 size = Vector3(7.06031, 5.05847, 2.48825) material = ExtResource("1_sb1vi") -[node name="CSGBox3D9" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] transform = Transform3D(-0.999949, 0.0101053, -8.74228e-08, 0.0101053, 0.999949, 0, 8.74183e-08, -8.83436e-10, -1, 1.46112, -0.431518, -12.5492) operation = 2 size = Vector3(10.2582, 5.05847, 2.48825) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGWorld/CSGBox3D5"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] transform = Transform3D(1, 0, 0, 0, 0.856465, 0.516204, 0, -0.516204, 0.856465, 11.0115, 0, -6.14323) operation = 2 size = Vector3(3.41214, 4.94897, 4.52136) material = ExtResource("1_sb1vi") -[node name="CSGBox3D" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0259626, -3.00393, -0.963224) size = Vector3(86.0781, 6, 106.223) material = ExtResource("1_etye1") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.295873, -0.0920334, -20.6882) size = Vector3(5.66602, 0.212601, 66.5905) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(0.951525, 0, 0.307573, 0, 1, 0, -0.307573, 0, 0.951525, 6.34913, -0.0920353, 30.9568) size = Vector3(5.66602, 0.212601, 40.6149) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGWorld"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld"] transform = Transform3D(0.979392, 0, 0.201967, 0, 1, 0, -0.201967, 0, 0.979392, 2.65383, -0.0920353, 13.0373) size = Vector3(5.66602, 0.212601, 22.0021) material = ExtResource("1_sb1vi") -[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] +[node name="CSGCombiner3D" type="CSGCombiner3D" parent="Level"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.7127, -3.8147e-06, -4.44497) use_collision = true -[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) size = Vector3(13.2101, 6.39868, 18.7856) material = ExtResource("1_sb1vi") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) operation = 2 size = Vector3(12.1248, 7.93005, 17.5173) material = ExtResource("1_sb1vi") -[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.50422, 4.57072, -8.66012) operation = 2 size = Vector3(2.34985, 3.30096, 3.98828) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) operation = 2 size = Vector3(1.52942, 1.75981, 1.18262) material = ExtResource("1_sb1vi") -[node name="CSGCombiner3D5" type="CSGCombiner3D" parent="."] +[node name="CSGCombiner3D5" type="CSGCombiner3D" parent="Level"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.3902, -3.8147e-06, -34.9045) use_collision = true -[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) size = Vector3(13.2101, 6.39868, 18.7856) material = ExtResource("1_sb1vi") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) operation = 2 size = Vector3(12.1248, 7.93005, 17.5173) material = ExtResource("1_sb1vi") -[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.44811, 4.70709, -8.66012) operation = 2 size = Vector3(2.34985, 3.30096, 4.2832) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D5"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D5"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) operation = 2 size = Vector3(1.52942, 1.75981, 1.18262) material = ExtResource("1_sb1vi") -[node name="CSGCombiner3D2" type="CSGCombiner3D" parent="."] +[node name="CSGCombiner3D2" type="CSGCombiner3D" parent="Level"] transform = Transform3D(0.947261, 0, 0.320464, 0, 1, 0, -0.320464, 0, 0.947261, -9.09123, 0, 34.072) use_collision = true -[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) size = Vector3(13.2101, 6.39868, 18.7856) material = ExtResource("1_sb1vi") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) operation = 2 size = Vector3(12.1248, 7.93005, 17.5173) material = ExtResource("1_sb1vi") -[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(-2.98023e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -2.98023e-08, -6.70552e-08, 1.43882, 4.72967, -8.66012) operation = 2 size = Vector3(2.34985, 3.30096, 4.33203) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D2"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D2"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) operation = 2 size = Vector3(1.52942, 1.75981, 1.18262) material = ExtResource("1_sb1vi") -[node name="CSGCombiner3D3" type="CSGCombiner3D" parent="."] +[node name="CSGCombiner3D3" type="CSGCombiner3D" parent="Level"] transform = Transform3D(-0.979862, 0, -0.199676, 0, 1, 0, 0.199676, 0, -0.979862, 18.4676, 0, 11.5749) use_collision = true -[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) size = Vector3(13.2101, 6.39868, 18.7856) material = ExtResource("1_sb1vi") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) operation = 2 size = Vector3(12.1248, 7.93005, 17.5173) material = ExtResource("1_sb1vi") -[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.55623, 4.44428, -8.66012) operation = 2 size = Vector3(2.34985, 3.30096, 3.71484) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D3"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D3"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) operation = 2 size = Vector3(1.52942, 1.75981, 1.18262) material = ExtResource("1_sb1vi") -[node name="CSGCombiner3D4" type="CSGCombiner3D" parent="."] +[node name="CSGCombiner3D4" type="CSGCombiner3D" parent="Level"] transform = Transform3D(-0.970654, 0, 0.240482, 0, 1, 0, -0.240482, 0, -0.970654, 19.1359, 0, -21.0191) use_collision = true -[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) size = Vector3(13.2101, 6.39868, 18.7856) material = ExtResource("1_sb1vi") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) operation = 2 size = Vector3(12.1248, 7.93005, 17.5173) material = ExtResource("1_sb1vi") -[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) operation = 2 size = Vector3(6.36378, 4.64685, 18.8601) material = ExtResource("1_sb1vi") -[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) operation = 2 size = Vector3(2.34985, 3.30096, 4) material = ExtResource("1_sb1vi") -[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.55623, 4.44428, -8.66012) operation = 2 size = Vector3(2.34985, 3.30096, 3.71484) material = ExtResource("1_sb1vi") -[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D4"] +[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D4"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) operation = 2 size = Vector3(1.52942, 1.75981, 1.18262) material = ExtResource("1_sb1vi") -[node name="Camera3D" type="Camera3D" parent="."] -transform = Transform3D(-0.882496, -0.0801336, 0.463442, -1.11759e-08, 0.985378, 0.170381, -0.470319, 0.150361, -0.869593, 13.939, 2.24424, -48.4686) -fov = 50.625 +[node name="PlayerActor" parent="." instance=ExtResource("3_vuk2b")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.6368, -0.00393009, -46.4616) diff --git a/project/maps/map.tscn b/project/maps/map.tscn index 1b3b8ddb..3b75753e 100644 --- a/project/maps/map.tscn +++ b/project/maps/map.tscn @@ -50,9 +50,9 @@ material_override = SubResource("StandardMaterial3D_oejri") mesh = SubResource("QuadMesh_oejri") [node name="LocaleMarker" type="LocaleMarker" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 19.8126, -1.90735e-06, -10.5129) locale_scene = "uid://bqaoxvqgrbi3v" entrance_path = "%CampEntrance" +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 19.8126, -1.90735e-06, -10.5129) [node name="MeshInstance3D" type="MeshInstance3D" parent="LocaleMarker"] material_override = SubResource("StandardMaterial3D_urvl1") diff --git a/project/objects/characters/player_actor.tscn b/project/objects/characters/player_actor.tscn new file mode 100644 index 00000000..568b74a6 --- /dev/null +++ b/project/objects/characters/player_actor.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=3 format=3 uid="uid://cykd1a23ria6k"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_7py3r"] + +[sub_resource type="CylinderMesh" id="CylinderMesh_66ixd"] + +[node name="PlayerActor" type="PlayerActor"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_7py3r") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +mesh = SubResource("CylinderMesh_66ixd") + +[node name="PlayerInput" type="PlayerInput" parent="."] +unique_name_in_owner = true + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 4.76837e-07, 1.8675, -2.90407) diff --git a/project/project.godot b/project/project.godot index e0cf7709..f9818ecd 100644 --- a/project/project.godot +++ b/project/project.godot @@ -14,3 +14,26 @@ config/name="authority" run/main_scene="uid://mn086drdvyym" config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://icon.svg" + +[input] + +move_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +move_forward={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +move_back={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} From 062633c74270382e0f0beda79ef66ce61af960aa Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 4 Jul 2025 15:59:45 +0200 Subject: [PATCH 7/8] feat: reorienting prototype goals --- modules/authority/locale_marker.cpp | 52 ------------------------- modules/authority/locale_marker.h | 27 ------------- modules/authority/party_member_data.cpp | 36 ----------------- modules/authority/party_member_data.h | 26 ------------- 4 files changed, 141 deletions(-) delete mode 100644 modules/authority/locale_marker.cpp delete mode 100644 modules/authority/locale_marker.h delete mode 100644 modules/authority/party_member_data.cpp delete mode 100644 modules/authority/party_member_data.h diff --git a/modules/authority/locale_marker.cpp b/modules/authority/locale_marker.cpp deleted file mode 100644 index 1bc7efec..00000000 --- a/modules/authority/locale_marker.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "locale_marker.h" -#include "authority/game_state.h" -#include "core/config/engine.h" -#include "core/input/input_enums.h" -#include "macros.h" - -void LocaleMarker::_bind_methods() { - BIND_HPROPERTY(Variant::STRING, locale_scene, PROPERTY_HINT_FILE, "*.tscn,*.scn"); - BIND_PROPERTY(Variant::STRING, entrance_path); -} - -void LocaleMarker::_notification(int what) { - if (Engine::get_singleton()->is_editor_hint()) { - return; - } - switch (what) { - default: - return; - case NOTIFICATION_READY: - this->ready(); - return; - } -} - -void LocaleMarker::ready() { - this->connect(this->sig_input_event, callable_mp(this, &self_type::on_input_event)); -} - -void LocaleMarker::on_input_event(Node *camera, Ref event, Vector3 position, Vector3 normal, int shape_ind) { - Ref clicked{ event }; - if (clicked.is_valid() && clicked->get_button_index() == MouseButton::LEFT) { - GameState::get_singleton()->set_locale_uid(this->locale_scene); - GameState::get_singleton()->set_locale_entrance_path(this->entrance_path); - get_tree()->change_scene_to_file(this->locale_scene); - } -} - -void LocaleMarker::set_locale_scene(String const &path) { - this->locale_scene = path; -} - -String LocaleMarker::get_locale_scene() const { - return this->locale_scene; -} - -void LocaleMarker::set_entrance_path(String const &node_path) { - this->entrance_path = node_path; -} - -String LocaleMarker::get_entrance_path() const { - return this->entrance_path; -} diff --git a/modules/authority/locale_marker.h b/modules/authority/locale_marker.h deleted file mode 100644 index 15295510..00000000 --- a/modules/authority/locale_marker.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef LOCALE_MARKER_H -#define LOCALE_MARKER_H - -#include "core/input/input_event.h" -#include "scene/3d/physics/area_3d.h" -#include "scene/main/node.h" - -class LocaleMarker : public Area3D { - GDCLASS(LocaleMarker, Area3D); - static void _bind_methods(); - void _notification(int what); - void ready(); - void on_input_event(Node *camera, Ref event, Vector3 position, Vector3 normal, int shape_ind); - -public: - void set_locale_scene(String const &value); - String get_locale_scene() const; - void set_entrance_path(String const &value); - String get_entrance_path() const; - -private: - String locale_scene{ "res://" }; - String entrance_path{ "%" }; - String const sig_input_event{ "input_event" }; -}; - -#endif // !LOCALE_MARKER_H diff --git a/modules/authority/party_member_data.cpp b/modules/authority/party_member_data.cpp deleted file mode 100644 index 46d95c8f..00000000 --- a/modules/authority/party_member_data.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "party_member_data.h" -#include "macros.h" - -void PartyMemberData::_bind_methods() { - BIND_PROPERTY(Variant::STRING, first_name); - BIND_PROPERTY(Variant::INT, player_trust); - BIND_PROPERTY(Variant::INT, player_fear); -} - -int PartyMemberData::get_player_authority() const { - return this->player_fear + this->player_trust; -} - -void PartyMemberData::set_first_name(String name) { - this->first_name = name; -} - -String PartyMemberData::get_first_name() const { - return this->first_name; -} - -void PartyMemberData::set_player_trust(int value) { - this->player_trust = value; -} - -int PartyMemberData::get_player_trust() const { - return this->player_trust; -} - -void PartyMemberData::set_player_fear(int value) { - this->player_fear = value; -} - -int PartyMemberData::get_player_fear() const { - return this->player_fear; -} diff --git a/modules/authority/party_member_data.h b/modules/authority/party_member_data.h deleted file mode 100644 index 91c9a5c1..00000000 --- a/modules/authority/party_member_data.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef PARTY_MEMBER_DATA_H -#define PARTY_MEMBER_DATA_H - -#include "core/io/resource.h" - -class PartyMemberData : public Resource { - GDCLASS(PartyMemberData, Resource); - static void _bind_methods(); - -public: - int get_player_authority() const; - - void set_first_name(String name); - String get_first_name() const; - void set_player_trust(int value); - int get_player_trust() const; - void set_player_fear(int value); - int get_player_fear() const; - -private: - String first_name{ "Firstname" }; - int player_trust{ 1 }; - int player_fear{ 1 }; -}; - -#endif // !PARTY_MEMBER_DATA_H From f7e07797c84157f9ab7ccdb2b09c43d52fe12846 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 4 Jul 2025 16:01:56 +0200 Subject: [PATCH 8/8] feat: implemented basic third person movement --- modules/authority/actor_body.cpp | 27 +- modules/authority/actor_body.h | 5 +- modules/authority/game_state.cpp | 43 +- modules/authority/game_state.h | 13 +- modules/authority/player_actor.cpp | 17 +- modules/authority/player_actor.h | 4 + modules/authority/player_input.cpp | 82 ++- modules/authority/player_input.h | 25 + modules/authority/register_types.cpp | 6 +- modules/authority/third_person_camera.cpp | 54 ++ modules/authority/third_person_camera.h | 29 + project/locales/city.tscn | 579 +------------------ project/maps/map.tscn | 126 ---- project/objects/characters/player_actor.tscn | 2 +- project/project.godot | 30 +- 15 files changed, 278 insertions(+), 764 deletions(-) create mode 100644 modules/authority/third_person_camera.cpp create mode 100644 modules/authority/third_person_camera.h delete mode 100644 project/maps/map.tscn diff --git a/modules/authority/actor_body.cpp b/modules/authority/actor_body.cpp index e2937295..1f995409 100644 --- a/modules/authority/actor_body.cpp +++ b/modules/authority/actor_body.cpp @@ -7,6 +7,16 @@ void ActorBody::_bind_methods() { BIND_HPROPERTY(Variant::FLOAT, movement_speed, PROPERTY_HINT_RANGE, "0.0,20.0"); } +void ActorBody::physics_process(double delta) { + if (this->teleport_on_process) { + set_global_position(this->teleport_target); + this->teleport_on_process = false; + force_update_transform(); + } + set_velocity(get_movement_direction() * this->movement_speed); + move_and_slide(); +} + void ActorBody::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; @@ -14,20 +24,18 @@ void ActorBody::_notification(int what) { switch (what) { default: return; + case NOTIFICATION_READY: + set_physics_process(true); + set_as_top_level(true); case NOTIFICATION_PHYSICS_PROCESS: physics_process(get_physics_process_delta_time()); return; } } -void ActorBody::physics_process(double delta) { - set_velocity(get_movement_direction() * this->movement_speed); - move_and_slide(); -} - void ActorBody::set_movement_direction(Vector3 direction) { this->mode = Direction; - this->movement_vector = { direction.x, 0.f, direction.y }; + this->movement_vector = Vector3(direction.x, 0.f, direction.z).normalized(); } Vector3 ActorBody::get_movement_direction() const { @@ -43,7 +51,7 @@ Vector3 ActorBody::get_movement_direction() const { void ActorBody::set_movement_target(Vector3 location) { this->mode = Position; - this->movement_vector = { location.x, 0.f, location.y }; + this->movement_vector = { location.x, 0.f, location.z }; } Vector3 ActorBody::get_movement_target() const { @@ -55,6 +63,11 @@ Vector3 ActorBody::get_movement_target() const { } } +void ActorBody::teleport(Vector3 target) { + this->teleport_target = target; + this->teleport_on_process = true; +} + void ActorBody::set_movement_speed(float speed) { this->movement_speed = speed; } diff --git a/modules/authority/actor_body.h b/modules/authority/actor_body.h index 5fb20086..fa7fbaac 100644 --- a/modules/authority/actor_body.h +++ b/modules/authority/actor_body.h @@ -20,15 +20,18 @@ public: Vector3 get_movement_direction() const; void set_movement_target(Vector3 location); Vector3 get_movement_target() const; + void teleport(Vector3 target); void set_movement_speed(float speed); float get_movement_speed() const; MovementMode get_movement_mode() const; private: - float movement_speed{ 1.f }; + float movement_speed{ 3.f }; Vector3 movement_vector{ 0.f, 0.f, 0.f }; MovementMode mode{ Direction }; + bool teleport_on_process{ false }; + Vector3 teleport_target{}; }; #endif //! ACTOR_BODY_H diff --git a/modules/authority/game_state.cpp b/modules/authority/game_state.cpp index e3a2e0f1..d10da4fd 100644 --- a/modules/authority/game_state.cpp +++ b/modules/authority/game_state.cpp @@ -3,14 +3,7 @@ GameState *GameState::singleton_instance{ nullptr }; -void GameState::_bind_methods() { - BIND_PROPERTY(Variant::STRING, locale_uid); - BIND_PROPERTY(Variant::STRING, locale_entrance_path); - { - String const party_member_data_hint{ vformat("%s/%s:PartyMemberData", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE) }; - BIND_HPROPERTY(Variant::ARRAY, player_party, PROPERTY_HINT_ARRAY_TYPE, party_member_data_hint); - } -} +void GameState::_bind_methods() {} GameState::GameState() { self_type::singleton_instance = this; @@ -23,37 +16,3 @@ GameState::~GameState() { GameState *GameState::get_singleton() { return self_type::singleton_instance; } - -void GameState::set_locale_uid(String const &value) { - this->locale_uid = value; -} - -String GameState::get_locale_uid() const { - return this->locale_uid; -} - -void GameState::set_locale_entrance_path(String const &value) { - this->locale_uid = value; -} - -String GameState::get_locale_entrance_path() const { - return this->locale_uid; -} - -void GameState::set_player_party(Array array) { - this->player_party.clear(); - for (int i{ 0 }; i < array.size(); ++i) { - Ref data{ array[i] }; - if (data.is_valid()) { - this->player_party.push_back(data); - } - } -} - -Array GameState::get_player_party() const { - Array a{}; - for (Ref const &data : this->player_party) { - a.push_back(data); - } - return a; -} diff --git a/modules/authority/game_state.h b/modules/authority/game_state.h index b3f0a7af..0170bd94 100644 --- a/modules/authority/game_state.h +++ b/modules/authority/game_state.h @@ -1,7 +1,7 @@ #ifndef GAME_STATE_H #define GAME_STATE_H -#include "authority/party_member_data.h" +#include "core/object/class_db.h" #include "core/object/object.h" #include "core/templates/vector.h" @@ -14,17 +14,6 @@ public: GameState(); virtual ~GameState(); static GameState *get_singleton(); - void set_locale_uid(String const &value); - String get_locale_uid() const; - void set_locale_entrance_path(String const &value); - String get_locale_entrance_path() const; - void set_player_party(Array array); - Array get_player_party() const; - -private: - String locale_uid{ "" }; - String locale_entrance_path{ "" }; - Vector> player_party{}; }; #endif // !GAME_STATE_H diff --git a/modules/authority/player_actor.cpp b/modules/authority/player_actor.cpp index 5bc08134..0401ec04 100644 --- a/modules/authority/player_actor.cpp +++ b/modules/authority/player_actor.cpp @@ -1,5 +1,7 @@ #include "player_actor.h" +#include "authority/game_state.h" #include "authority/player_input.h" +#include "scene/main/viewport.h" void PlayerActor::_bind_methods() { } @@ -7,10 +9,20 @@ void PlayerActor::_bind_methods() { void PlayerActor::ready() { PlayerInput *input{ cast_to(get_node(NodePath("%PlayerInput"))) }; input->connect(PlayerInput::signal_movement, callable_mp(this, &self_type::input_move)); + set_process(true); +} + +void PlayerActor::process(double delta) { + Basis const basis{ this->get_viewport()->get_camera_3d()->get_global_basis() }; + Vector3 x{ basis.get_column(0) }; + x = Vector3{ x.x, 0.f, x.z }.normalized(); + Vector3 z{ basis.get_column(2) }; + z = Vector3{ z.x, 0.f, z.z }.normalized(); + set_movement_direction(x * this->move_input.x + z * this->move_input.y); } void PlayerActor::input_move(Vector2 movement) { - set_movement_direction({ movement.x, 0.f, movement.y }); + this->move_input = movement; } void PlayerActor::_notification(int what) { @@ -23,5 +35,8 @@ void PlayerActor::_notification(int what) { case NOTIFICATION_READY: ready(); return; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + return; } } diff --git a/modules/authority/player_actor.h b/modules/authority/player_actor.h index af7bd862..6cdcdc59 100644 --- a/modules/authority/player_actor.h +++ b/modules/authority/player_actor.h @@ -7,10 +7,14 @@ class PlayerActor : public ActorBody { GDCLASS(PlayerActor, ActorBody); static void _bind_methods(); void ready(); + void process(double delta); void input_move(Vector2 movement); public: void _notification(int what); + +private: + Vector2 move_input{ 0.f, 0.f }; }; #endif // !PLAYER_ACTOR_H diff --git a/modules/authority/player_input.cpp b/modules/authority/player_input.cpp index 4228c55d..bfd00590 100644 --- a/modules/authority/player_input.cpp +++ b/modules/authority/player_input.cpp @@ -4,13 +4,21 @@ #include "macros.h" String const PlayerInput::signal_movement{ "movement" }; +String const PlayerInput::signal_look{ "look" }; +String const PlayerInput::signal_mouselook{ "mouselook" }; void PlayerInput::_bind_methods() { BIND_PROPERTY(Variant::STRING, action_move_left); BIND_PROPERTY(Variant::STRING, action_move_right); BIND_PROPERTY(Variant::STRING, action_move_forward); BIND_PROPERTY(Variant::STRING, action_move_back); + BIND_PROPERTY(Variant::STRING, action_look_left); + BIND_PROPERTY(Variant::STRING, action_look_right); + BIND_PROPERTY(Variant::STRING, action_look_up); + BIND_PROPERTY(Variant::STRING, action_look_down); ADD_SIGNAL(MethodInfo(self_type::signal_movement, PropertyInfo(Variant::VECTOR2, "movement_directions"))); + ADD_SIGNAL(MethodInfo(self_type::signal_look, PropertyInfo(Variant::VECTOR2, "look_delta"))); + ADD_SIGNAL(MethodInfo(self_type::signal_mouselook, PropertyInfo(Variant::VECTOR2, "mouse_delta"))); } void PlayerInput::_notification(int what) { @@ -21,22 +29,56 @@ void PlayerInput::_notification(int what) { default: return; case NOTIFICATION_READY: - this->set_process_unhandled_input(true); + set_process_unhandled_input(true); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); return; } } void PlayerInput::unhandled_input(Ref const &event) { Input *input{ Input::get_singleton() }; + bool is_movement_action{ event->is_action(self_type::action_move_left) }; is_movement_action |= event->is_action(self_type::action_move_right); is_movement_action |= event->is_action(self_type::action_move_forward); is_movement_action |= event->is_action(self_type::action_move_back); if (is_movement_action) { - float const h_axis{ input->get_axis(self_type::action_move_right, self_type::action_move_left) }; - float const v_axis{ input->get_axis(self_type::action_move_back, self_type::action_move_forward) }; - this->emit_signal(self_type::signal_movement, Vector2{ h_axis, v_axis }); + float const h_axis{ input->get_axis(self_type::action_move_left, self_type::action_move_right) }; + float const v_axis{ input->get_axis(self_type::action_move_forward, self_type::action_move_back) }; + emit_signal(self_type::signal_movement, Vector2{ h_axis, v_axis }); } + + bool is_look_action{ event->is_action(self_type::action_look_left) }; + is_look_action |= event->is_action(self_type::action_look_right); + is_look_action |= event->is_action(self_type::action_look_up); + is_look_action |= event->is_action(self_type::action_look_down); + if (is_look_action) { + float const h_axis{ input->get_axis(self_type::action_look_right, self_type::action_look_left) }; + float const v_axis{ input->get_axis(self_type::action_look_down, self_type::action_look_up) }; + emit_signal(self_type::signal_look, Vector2{ h_axis, v_axis } * this->look_speed); + } + + Ref mouse_motion_action{ event }; + if (mouse_motion_action.is_valid()) { + Vector2 const velocity{ mouse_motion_action->get_relative() }; + emit_signal(self_type::signal_mouselook, velocity * this->mouselook_speed); + } +} + +void PlayerInput::set_mouselook_speed(Vector2 speed) { + this->mouselook_speed = speed; +} + +Vector2 PlayerInput::get_mouselook_speed() const { + return this->mouselook_speed; +} + +void PlayerInput::set_look_speed(Vector2 speed) { + this->look_speed = speed; +} + +Vector2 PlayerInput::get_look_speed() const { + return this->look_speed; } void PlayerInput::set_action_move_left(String action) { @@ -70,3 +112,35 @@ void PlayerInput::set_action_move_back(String action) { String PlayerInput::get_action_move_back() const { return this->action_move_back; } + +void PlayerInput::set_action_look_left(String action) { + this->action_look_left = action; +} + +String PlayerInput::get_action_look_left() const { + return this->action_look_left; +} + +void PlayerInput::set_action_look_right(String action) { + this->action_look_right = action; +} + +String PlayerInput::get_action_look_right() const { + return this->action_look_right; +} + +void PlayerInput::set_action_look_up(String action) { + this->action_look_up = action; +} + +String PlayerInput::get_action_look_up() const { + return this->action_look_up; +} + +void PlayerInput::set_action_look_down(String action) { + this->action_look_down = action; +} + +String PlayerInput::get_action_look_down() const { + return this->action_look_down; +} diff --git a/modules/authority/player_input.h b/modules/authority/player_input.h index 7dba0ec4..977dc2a1 100644 --- a/modules/authority/player_input.h +++ b/modules/authority/player_input.h @@ -11,6 +11,12 @@ class PlayerInput : public Node { public: void _notification(int what); virtual void unhandled_input(Ref const &event) override; + + void set_mouselook_speed(Vector2 speed); + Vector2 get_mouselook_speed() const; + void set_look_speed(Vector2 speed); + Vector2 get_look_speed() const; + void set_action_move_left(String action); String get_action_move_left() const; void set_action_move_right(String action); @@ -20,14 +26,33 @@ public: void set_action_move_back(String action); String get_action_move_back() const; + void set_action_look_left(String action); + String get_action_look_left() const; + void set_action_look_right(String action); + String get_action_look_right() const; + void set_action_look_up(String action); + String get_action_look_up() const; + void set_action_look_down(String action); + String get_action_look_down() const; + public: static String const signal_movement; + static String const signal_look; + static String const signal_mouselook; private: + Vector2 mouselook_speed{ 0.001f, 0.001f }; + Vector2 look_speed{ 1.75f, 1.75f }; + String action_move_left{ "move_left" }; String action_move_right{ "move_right" }; String action_move_forward{ "move_forward" }; String action_move_back{ "move_back" }; + + String action_look_left{ "look_left" }; + String action_look_right{ "look_right" }; + String action_look_up{ "look_up" }; + String action_look_down{ "look_down" }; }; #endif // !PLAYER_INPUT_H diff --git a/modules/authority/register_types.cpp b/modules/authority/register_types.cpp index 0d44b7d7..8d674102 100644 --- a/modules/authority/register_types.cpp +++ b/modules/authority/register_types.cpp @@ -2,10 +2,9 @@ #include "authority/actor_body.h" #include "authority/game_state.h" -#include "authority/locale_marker.h" -#include "authority/party_member_data.h" #include "authority/player_actor.h" #include "authority/player_input.h" +#include "authority/third_person_camera.h" #include "core/config/engine.h" #include "core/object/class_db.h" @@ -16,11 +15,10 @@ void initialize_authority_module(ModuleInitializationLevel p_level) { return; } GDREGISTER_CLASS(GameState); - GDREGISTER_RUNTIME_CLASS(LocaleMarker); - GDREGISTER_RUNTIME_CLASS(PartyMemberData); GDREGISTER_CLASS(ActorBody); GDREGISTER_CLASS(PlayerActor); GDREGISTER_CLASS(PlayerInput); + GDREGISTER_CLASS(ThirdPersonCamera); game_state = memnew(GameState); Engine::get_singleton()->add_singleton(Engine::Singleton("GameState", GameState::get_singleton())); diff --git a/modules/authority/third_person_camera.cpp b/modules/authority/third_person_camera.cpp new file mode 100644 index 00000000..04077cc6 --- /dev/null +++ b/modules/authority/third_person_camera.cpp @@ -0,0 +1,54 @@ +#include "third_person_camera.h" +#include "player_input.h" + +void ThirdPersonCamera::_bind_methods() { +} + +void ThirdPersonCamera::ready() { + set_process(true); + if (PlayerInput * player_input{ cast_to(get_node(NodePath("%PlayerInput"))) }) { + player_input->connect(PlayerInput::signal_look, callable_mp(this, &self_type::on_look_input)); + player_input->connect(PlayerInput::signal_mouselook, callable_mp(this, &self_type::on_mouselook_input)); + } +} + +void ThirdPersonCamera::process(double delta) { + this->look_rotation += look_rotation_motion * delta; + this->look_rotation.y = CLAMP(this->look_rotation.y, -Math_PI / 2.5, Math_PI / 2.5); + Vector3 pivot{ get_parent_node_3d()->get_global_position() }; + pivot.y += this->height; + Vector3 offset{ 0.f, 0.f, this->distance }; + offset.rotate({ 1.f, 0.f, 0.f }, this->look_rotation.y); + offset.rotate({ 0.f, 1.f, 0.f }, this->look_rotation.x); + look_at_from_position(pivot + offset, pivot); +} + +void ThirdPersonCamera::on_look_input(Vector2 input) { + this->look_rotation_motion = input; +} + +void ThirdPersonCamera::on_mouselook_input(Vector2 input) { + this->look_rotation -= input; +} + +void ThirdPersonCamera::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + case NOTIFICATION_READY: + ready(); + break; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + break; + } +} + +void ThirdPersonCamera::set_base_rotation_speed(Vector2 value) { + this->base_rotation_speed = value; +} + +Vector2 ThirdPersonCamera::get_base_rotation_speed() const { + return this->base_rotation_speed; +} diff --git a/modules/authority/third_person_camera.h b/modules/authority/third_person_camera.h new file mode 100644 index 00000000..9ec2935d --- /dev/null +++ b/modules/authority/third_person_camera.h @@ -0,0 +1,29 @@ +#ifndef THIRD_PERSON_CAMERA_H +#define THIRD_PERSON_CAMERA_H + +#include "scene/3d/camera_3d.h" + +class ThirdPersonCamera : public Camera3D { + GDCLASS(ThirdPersonCamera, Camera3D); + static void _bind_methods(); + void ready(); + void process(double delta); + void on_look_input(Vector2 input); + void on_mouselook_input(Vector2 input); + +public: + void _notification(int what); + + void set_base_rotation_speed(Vector2 value); + Vector2 get_base_rotation_speed() const; + +private: + Vector2 look_rotation_motion{ 0.f, 0.f }; + Vector2 look_rotation{ 0.f, 0.f }; + + Vector2 base_rotation_speed{ 0.1f, 0.1f }; + float distance{ 3.f }; + float height{ 2.2f }; +}; + +#endif // !THIRD_PERSON_CAMERA_H diff --git a/project/locales/city.tscn b/project/locales/city.tscn index 45461d8d..c31fb667 100644 --- a/project/locales/city.tscn +++ b/project/locales/city.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=7 format=3 uid="uid://bqaoxvqgrbi3v"] +[gd_scene load_steps=6 format=3 uid="uid://bqaoxvqgrbi3v"] [ext_resource type="Material" uid="uid://cbuk8uxxuj7j5" path="res://materials/grids/grass.tres" id="1_etye1"] -[ext_resource type="Material" uid="uid://ke4yek3xtin5" path="res://materials/grids/bricks.tres" id="1_sb1vi"] [ext_resource type="PackedScene" uid="uid://cykd1a23ria6k" path="res://objects/characters/player_actor.tscn" id="3_vuk2b"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_sb1vi"] @@ -19,572 +18,22 @@ glow_enabled = true [node name="City" type="Node"] -[node name="PartySelectionUI" type="CanvasLayer" parent="."] - -[node name="VBoxContainer" type="VBoxContainer" parent="PartySelectionUI"] -anchors_preset = 6 -anchor_left = 1.0 -anchor_top = 0.5 -anchor_right = 1.0 -anchor_bottom = 0.5 -offset_left = -298.0 -offset_top = -211.0 -offset_bottom = 211.0 -grow_horizontal = 0 -grow_vertical = 2 - -[node name="Level" type="Node3D" parent="."] - -[node name="WorldEnvironment" type="WorldEnvironment" parent="Level"] +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_wwygw") -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Level"] -transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0) +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) shadow_enabled = true -[node name="CSGWorld" type="CSGCombiner3D" parent="Level"] -use_collision = true - -[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.7726, 1.24028, -3.26613) -size = Vector3(29.3063, 2.53036, 32.2042) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -operation = 2 -size = Vector3(28.3818, 4.94897, 31.2627) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.3707, 0, 8.21931) -operation = 2 -size = Vector3(5.48248, 4.94897, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(0.996095, -0.0882858, 0, 0.0882858, 0.996095, 0, 0, 0, 1, -4.27235, 1.64007, -16.0551) -operation = 2 -size = Vector3(17.209, 2.77515, 1.67773) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D11" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(-0.662908, 0.748701, 0, -0.748701, -0.662908, 0, 0, 0, 1, 1.99536, 0.140041, -16.0551) -operation = 2 -size = Vector3(3.51099, 4.26892, 1.67773) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D12" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(0.0515306, -0.596407, 0.801026, -0.589269, -0.665739, -0.45777, 0.806292, -0.448431, -0.38575, 13.6247, 0.402275, -15.0203) -operation = 2 -size = Vector3(4.65393, 4.26892, 4.29919) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(1, 0, 0, 0, 0.990234, 0.139415, 0, -0.139415, 0.990234, -15.0347, 1.84148, -10.1624) -operation = 2 -size = Vector3(5.48248, 4.94897, 15.628) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(0.996356, 0.0852952, 0, -0.0852952, 0.996356, 0, 0, 0, 1, -6.08641, 2.3849, 15.0748) -operation = 2 -size = Vector3(18.0761, 4.49255, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D13" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(0.940934, 0.33859, 0, -0.33859, 0.940934, 0, 0, 0, 1, 10.9771, 1.22338, 15.0748) -operation = 2 -size = Vector3(5.48767, 4.49255, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(0.998184, -0.0602297, 0, 0.0602297, 0.998184, 0, 0, 0, 1, -11.169, 1.83497, 16.5285) -operation = 2 -size = Vector3(7.92215, 4.49255, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D2"] -transform = Transform3D(0.938076, -0.346428, 0, 0.346428, 0.938076, 0, 0, 0, 1, -8.1568, 0.67643, 16.5285) -operation = 2 -size = Vector3(4.54713, 4.49255, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 17.3635, 1.24027, -22.297) -size = Vector3(29.3063, 2.53036, 32.2042) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -operation = 2 -size = Vector3(28.3818, 4.94897, 31.2627) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.3707, 0, 8.21931) -operation = 2 -size = Vector3(5.48248, 4.94897, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.67738, 1.90735e-06, -15.8587) -operation = 2 -size = Vector3(11.8087, 4.94897, 1.39062) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -transform = Transform3D(0.983341, 0.181772, 0, -0.181772, 0.983341, 0, 0, 0, 1, 5.71055, 0.339279, 15.5698) -operation = 2 -size = Vector3(9.78, 4.23425, 1.39062) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -14.4351, 1.90735e-06, -3.8005) -operation = 2 -size = Vector3(11.8087, 4.94897, 1.39062) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -transform = Transform3D(0.835299, 0.549796, 0, -0.549796, 0.835299, 0, 0, 0, 1, -2.58652, 1.00152, -15.8587) -operation = 2 -size = Vector3(2.53568, 4.46423, 1.39062) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D9"] -transform = Transform3D(0.835299, 0.549796, -9.2008e-09, -0.491933, 0.747388, 0.446557, 0.245515, -0.373009, 0.894755, -14.5944, -0.54182, -15.1699) -operation = 2 -size = Vector3(3, 4.46423, 2.88232) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(0.94881, 0, 0.315848, 0, 1, 0, -0.315848, 0, 0.94881, -7.66859, 1.24028, 32.2569) -size = Vector3(22.6908, 2.53036, 26.0577) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -operation = 2 -size = Vector3(21.699, 4.94897, 24.7637) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) -operation = 2 -size = Vector3(5.48248, 4.94897, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D12" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(0.966641, 0.256107, 0.00379327, -0.221096, 0.841791, -0.492448, -0.129312, 0.475181, 0.870333, 10.1198, 1.29747, 12.165) -operation = 2 -size = Vector3(5.48248, 4.94897, 5.69867) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(0.861603, -0.507583, 0, 0.507583, 0.861603, 0, 0, 0, 1, 1.68174, 0.365051, 12.4396) -operation = 2 -size = Vector3(5.18265, 4.66061, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(0.956661, -0.291203, 0, 0.291203, 0.956661, 0, 8.9407e-08, -7.45058e-09, 1, -5.16157, 2.49941, 12.5804) -operation = 2 -size = Vector3(8.79707, 4.04699, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D11" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(-1.49012e-07, 6.70552e-08, -1, 0.291203, 0.956661, 0, 0.956661, -0.291203, -5.96046e-08, -10.3324, 0.55706, 9.10962) -operation = 2 -size = Vector3(8.30031, 5.37523, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(0.942027, 0.335534, 0, -0.335534, 0.942028, 0, 2.38419e-07, 7.45058e-08, 1, 1.96285, 0.912893, -11.3267) -operation = 2 -size = Vector3(20.6193, 10.1297, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(2.98023e-07, -2.98023e-08, 1, 0.477634, 0.878559, 0, -0.878558, 0.477634, 0, -11.4397, 0.843881, -2.17569) -operation = 2 -size = Vector3(9.11396, 5.37523, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D4"] -transform = Transform3D(1.19209e-07, -4.47035e-08, 1, 0.22165, 0.975126, 0, -0.975125, 0.22165, 0, -11.4397, -1.17258, -1.42908) -operation = 2 -size = Vector3(9.26142, 5.37523, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(-0.980662, 0, -0.195706, 0, 1, 0, 0.195706, 0, -0.980662, 16.4482, 1.24028, 10.8159) -size = Vector3(22.6908, 2.53036, 26.0577) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -operation = 2 -size = Vector3(21.699, 4.94897, 24.7637) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) -operation = 2 -size = Vector3(5.48248, 4.94897, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D11" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, 9.81546, 1.02972, -11.1309) -operation = 2 -size = Vector3(5.48248, 2.88953, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D12" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(0.968409, -0.249366, -7.45058e-08, 0.249366, 0.968409, 0, 7.21521e-08, -1.85792e-08, 1, 7.47525, 1.68203, -11.1309) -operation = 2 -size = Vector3(5.48248, 2.88953, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, -7.5132, 2.28486, -10.4518) -operation = 2 -size = Vector3(8.62306, 4.94897, 5.58841) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D10" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(0.920047, -0.391807, -7.45058e-08, 0.391807, 0.920047, 0, 7.45058e-08, -2.98023e-08, 1, -6.59657, 0.52667, -12.3894) -operation = 2 -size = Vector3(7.21283, 3.23804, 1.71315) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(1, 0, -7.45058e-08, 0, 1, 0, 7.45058e-08, 0, 1, -1.74361, 1.34271, 10.7097) -operation = 2 -size = Vector3(19.7208, 2.26355, 5.36632) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(0.90949, -0.415725, -7.45058e-08, 0.415725, 0.90949, 0, 5.96046e-08, -2.98023e-08, 1, 6.5508, 1.03969, 12.4855) -operation = 2 -size = Vector3(3.29733, 2.26355, 1.9962) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D7"] -transform = Transform3D(0.872811, 0.488058, -7.45058e-08, -0.488058, 0.872811, 0, 5.96046e-08, 4.47035e-08, 1, 3.25758, 0.0104947, 12.4855) -operation = 2 -size = Vector3(3.29733, 3.41986, 1.9962) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.4648, 1.24028, -35.2034) -size = Vector3(22.6908, 2.53036, 26.0577) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] -operation = 2 -size = Vector3(21.699, 4.94897, 24.7637) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.81546, 0, 1.44135) -operation = 2 -size = Vector3(5.48248, 4.94897, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] -transform = Transform3D(0.922282, -0.386518, 0, 0.386518, 0.922282, 0, 0, 0, 1, -1.86533, 0.1865, 12.965) -operation = 2 -size = Vector3(7.06031, 5.05847, 2.48825) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] -transform = Transform3D(-4.03142e-08, 1.68952e-08, 1, 0.386518, 0.922282, 0, -0.922282, 0.386518, -4.37114e-08, -10.9717, 0.1865, -0.139679) -operation = 2 -size = Vector3(7.06031, 5.05847, 2.48825) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D9" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] -transform = Transform3D(-0.999949, 0.0101053, -8.74228e-08, 0.0101053, 0.999949, 0, 8.74183e-08, -8.83436e-10, -1, 1.46112, -0.431518, -12.5492) -operation = 2 -size = Vector3(10.2582, 5.05847, 2.48825) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGWorld/CSGBox3D5"] -transform = Transform3D(1, 0, 0, 0, 0.856465, 0.516204, 0, -0.516204, 0.856465, 11.0115, 0, -6.14323) -operation = 2 -size = Vector3(3.41214, 4.94897, 4.52136) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0259626, -3.00393, -0.963224) -size = Vector3(86.0781, 6, 106.223) -material = ExtResource("1_etye1") - -[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.295873, -0.0920334, -20.6882) -size = Vector3(5.66602, 0.212601, 66.5905) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(0.951525, 0, 0.307573, 0, 1, 0, -0.307573, 0, 0.951525, 6.34913, -0.0920353, 30.9568) -size = Vector3(5.66602, 0.212601, 40.6149) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGWorld"] -transform = Transform3D(0.979392, 0, 0.201967, 0, 1, 0, -0.201967, 0, 0.979392, 2.65383, -0.0920353, 13.0373) -size = Vector3(5.66602, 0.212601, 22.0021) -material = ExtResource("1_sb1vi") - -[node name="CSGCombiner3D" type="CSGCombiner3D" parent="Level"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.7127, -3.8147e-06, -4.44497) -use_collision = true - -[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) -size = Vector3(13.2101, 6.39868, 18.7856) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) -operation = 2 -size = Vector3(12.1248, 7.93005, 17.5173) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.50422, 4.57072, -8.66012) -operation = 2 -size = Vector3(2.34985, 3.30096, 3.98828) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) -operation = 2 -size = Vector3(1.52942, 1.75981, 1.18262) -material = ExtResource("1_sb1vi") - -[node name="CSGCombiner3D5" type="CSGCombiner3D" parent="Level"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.3902, -3.8147e-06, -34.9045) -use_collision = true - -[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) -size = Vector3(13.2101, 6.39868, 18.7856) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) -operation = 2 -size = Vector3(12.1248, 7.93005, 17.5173) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.44811, 4.70709, -8.66012) -operation = 2 -size = Vector3(2.34985, 3.30096, 4.2832) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D5"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) -operation = 2 -size = Vector3(1.52942, 1.75981, 1.18262) -material = ExtResource("1_sb1vi") - -[node name="CSGCombiner3D2" type="CSGCombiner3D" parent="Level"] -transform = Transform3D(0.947261, 0, 0.320464, 0, 1, 0, -0.320464, 0, 0.947261, -9.09123, 0, 34.072) -use_collision = true - -[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) -size = Vector3(13.2101, 6.39868, 18.7856) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) -operation = 2 -size = Vector3(12.1248, 7.93005, 17.5173) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(-2.98023e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -2.98023e-08, -6.70552e-08, 1.43882, 4.72967, -8.66012) -operation = 2 -size = Vector3(2.34985, 3.30096, 4.33203) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D2"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) -operation = 2 -size = Vector3(1.52942, 1.75981, 1.18262) -material = ExtResource("1_sb1vi") - -[node name="CSGCombiner3D3" type="CSGCombiner3D" parent="Level"] -transform = Transform3D(-0.979862, 0, -0.199676, 0, 1, 0, 0.199676, 0, -0.979862, 18.4676, 0, 11.5749) -use_collision = true - -[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) -size = Vector3(13.2101, 6.39868, 18.7856) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) -operation = 2 -size = Vector3(12.1248, 7.93005, 17.5173) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.55623, 4.44428, -8.66012) -operation = 2 -size = Vector3(2.34985, 3.30096, 3.71484) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D3"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) -operation = 2 -size = Vector3(1.52942, 1.75981, 1.18262) -material = ExtResource("1_sb1vi") - -[node name="CSGCombiner3D4" type="CSGCombiner3D" parent="Level"] -transform = Transform3D(-0.970654, 0, 0.240482, 0, 1, 0, -0.240482, 0, -0.970654, 19.1359, 0, -21.0191) -use_collision = true - -[node name="CSGBox3D" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.943035, 2.69934, 0.370387) -size = Vector3(13.2101, 6.39868, 18.7856) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D3" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.779079, 3.9671, 0.421809) -operation = 2 -size = Vector3(12.1248, 7.93005, 17.5173) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.05528, 5.6087, 1.09461) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D5" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(1, 0, 0, 0, 0.993972, -0.10963, 0, 0.10963, 0.993972, -6.20065, 6.81794, -1.62846) -operation = 2 -size = Vector3(6.36378, 4.64685, 18.8601) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D6" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -2.90541, 6.09294, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D7" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(-4.11049e-08, 0.441193, 0.897412, 1.48684e-08, 0.897412, -0.441193, -1, -4.79209e-09, -4.34479e-08, -0.501738, 6.60845, 9.63982) -operation = 2 -size = Vector3(2.34985, 3.30096, 4) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D8" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(-4.11049e-08, 0.924792, 0.380473, 1.48684e-08, 0.380473, -0.924792, -1, -3.23565e-08, -2.93895e-08, 1.55623, 4.44428, -8.66012) -operation = 2 -size = Vector3(2.34985, 3.30096, 3.71484) -material = ExtResource("1_sb1vi") - -[node name="CSGBox3D4" type="CSGBox3D" parent="Level/CSGCombiner3D4"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47246, 0.911386, 4.88385) -operation = 2 -size = Vector3(1.52942, 1.75981, 1.18262) -material = ExtResource("1_sb1vi") +[node name="CampEntrance" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.2797, -0.00393486, -42.0831) [node name="PlayerActor" parent="." instance=ExtResource("3_vuk2b")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.6368, -0.00393009, -46.4616) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0171704, -0.00572681, 0.28793) + +[node name="CSGBox3D" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.505729, 0) +use_collision = true +size = Vector3(100, 1, 100) +material = ExtResource("1_etye1") diff --git a/project/maps/map.tscn b/project/maps/map.tscn deleted file mode 100644 index 3b75753e..00000000 --- a/project/maps/map.tscn +++ /dev/null @@ -1,126 +0,0 @@ -[gd_scene load_steps=11 format=3 uid="uid://mn086drdvyym"] - -[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_oejri"] -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_urvl1"] -sky_material = SubResource("ProceduralSkyMaterial_oejri") - -[sub_resource type="Environment" id="Environment_ers5l"] -background_mode = 2 -sky = SubResource("Sky_urvl1") -tonemap_mode = 2 -glow_enabled = true - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_oejri"] -albedo_color = Color(0.16206, 0.18, 0.1332, 1) - -[sub_resource type="QuadMesh" id="QuadMesh_oejri"] -size = Vector2(100, 100) -orientation = 1 - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_urvl1"] -albedo_color = Color(0.21, 0.232, 0.25, 1) - -[sub_resource type="CylinderMesh" id="CylinderMesh_ers5l"] -top_radius = 10.0 -bottom_radius = 10.0 -height = 0.5 - -[sub_resource type="CylinderShape3D" id="CylinderShape3D_c3pkw"] -radius = 2.86377 - -[sub_resource type="PrismMesh" id="PrismMesh_oejri"] - -[sub_resource type="BoxMesh" id="BoxMesh_oejri"] -size = Vector3(0.53, 0.56, 1) - -[node name="Map" type="Node3D"] - -[node name="WorldEnvironment" type="WorldEnvironment" parent="."] -environment = SubResource("Environment_ers5l") - -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] -transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) -shadow_enabled = true - -[node name="MeshInstance3D" type="MeshInstance3D" parent="."] -material_override = SubResource("StandardMaterial3D_oejri") -mesh = SubResource("QuadMesh_oejri") - -[node name="LocaleMarker" type="LocaleMarker" parent="."] -locale_scene = "uid://bqaoxvqgrbi3v" -entrance_path = "%CampEntrance" -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 19.8126, -1.90735e-06, -10.5129) - -[node name="MeshInstance3D" type="MeshInstance3D" parent="LocaleMarker"] -material_override = SubResource("StandardMaterial3D_urvl1") -mesh = SubResource("CylinderMesh_ers5l") - -[node name="CollisionShape3D" type="CollisionShape3D" parent="LocaleMarker"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1601, 0, 4.78461) -shape = SubResource("CylinderShape3D_c3pkw") - -[node name="Label3D" type="Label3D" parent="LocaleMarker"] -transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, 0, 1.03264, 0) -pixel_size = 0.1 -text = "City -" - -[node name="Label3D2" type="Label3D" parent="LocaleMarker"] -transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, -14.3197, 1.03264, 2.5534) -pixel_size = 0.05 -text = "Camp" - -[node name="Label3D3" type="Label3D" parent="LocaleMarker"] -transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, -15.5085, 1.03264, 4.74225) -pixel_size = 0.05 -modulate = Color(1, 0, 0, 1) -text = "! -" - -[node name="MeshInstance3D2" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -15.7257, 0, 5.36808) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D3" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -15.7232, 0, 4.67118) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D4" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -15.807, 0, 4.03467) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D5" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.7496, -4.76837e-07, 2.95756) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D6" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.2813, -4.76837e-07, 3.76329) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D7" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.2956, -4.76837e-07, 4.4297) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D8" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.3204, -4.76837e-07, 5.30799) -mesh = SubResource("PrismMesh_oejri") - -[node name="MeshInstance3D9" type="MeshInstance3D" parent="LocaleMarker"] -transform = Transform3D(-0.0195116, 0, 0.99981, 0, 1, 0, -0.99981, 0, -0.0195116, -13.3516, -4.76837e-07, 6.29061) -mesh = SubResource("PrismMesh_oejri") - -[node name="Camera3D" type="Camera3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 0.258819, 0.965926, 0, -0.965926, 0.258819, 0, 26.4443, 6.29706) -fov = 52.6 - -[node name="MeshInstance3D2" type="MeshInstance3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.292486, 0) -mesh = SubResource("BoxMesh_oejri") - -[node name="Label3D" type="Label3D" parent="MeshInstance3D2"] -transform = Transform3D(1, 0, 4.37114e-08, -4.37114e-08, 1.91069e-15, 1, 0, -1, 1.91069e-15, 0, 1.03264, -0.956246) -pixel_size = 0.05 -text = "You" diff --git a/project/objects/characters/player_actor.tscn b/project/objects/characters/player_actor.tscn index 568b74a6..c499369d 100644 --- a/project/objects/characters/player_actor.tscn +++ b/project/objects/characters/player_actor.tscn @@ -17,5 +17,5 @@ mesh = SubResource("CylinderMesh_66ixd") [node name="PlayerInput" type="PlayerInput" parent="."] unique_name_in_owner = true -[node name="Camera3D" type="Camera3D" parent="."] +[node name="Camera3D" type="ThirdPersonCamera" parent="."] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 4.76837e-07, 1.8675, -2.90407) diff --git a/project/project.godot b/project/project.godot index f9818ecd..0ee1b8b4 100644 --- a/project/project.godot +++ b/project/project.godot @@ -11,29 +11,57 @@ config_version=5 [application] config/name="authority" -run/main_scene="uid://mn086drdvyym" +run/main_scene="uid://bqaoxvqgrbi3v" config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://icon.svg" +[display] + +window/vsync/vsync_mode=2 + [input] move_left={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) ] } move_right={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) ] } move_forward={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) ] } move_back={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +look_left={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) +] +} +look_right={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) +] +} +look_up={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) +] +} +look_down={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) ] }