diff --git a/Mr. Brick Adventures.sln.DotSettings.user b/Mr. Brick Adventures.sln.DotSettings.user index e752dd6..122ad95 100644 --- a/Mr. Brick Adventures.sln.DotSettings.user +++ b/Mr. Brick Adventures.sln.DotSettings.user @@ -1,6 +1,7 @@  ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/addons/phantom_camera/icons/viewfinder/Select.svg b/addons/phantom_camera/icons/viewfinder/Select.svg new file mode 100644 index 0000000..34b109b --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Select.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/phantom_camera/icons/viewfinder/Select.svg.import b/addons/phantom_camera/icons/viewfinder/Select.svg.import new file mode 100644 index 0000000..81b41c9 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Select.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rghrkoqrm2ig" +path="res://.godot/imported/Select.svg-cdf90b8b400d3b91a023b70c6a823894.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/viewfinder/Select.svg" +dest_files=["res://.godot/imported/Select.svg-cdf90b8b400d3b91a023b70c6a823894.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +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=1 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/warning.svg b/addons/phantom_camera/icons/warning.svg new file mode 100644 index 0000000..63dbedf --- /dev/null +++ b/addons/phantom_camera/icons/warning.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/icons/warning.svg.import b/addons/phantom_camera/icons/warning.svg.import new file mode 100644 index 0000000..2895b37 --- /dev/null +++ b/addons/phantom_camera/icons/warning.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjlv0bg7byjx0" +path="res://.godot/imported/warning.svg-c1b21c265e0842bbdc9ed10735995366.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/warning.svg" +dest_files=["res://.godot/imported/warning.svg-c1b21c265e0842bbdc9ed10735995366.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +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=1 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/panel/viewfinder/host_list/host_list.tscn b/addons/phantom_camera/panel/viewfinder/host_list/host_list.tscn new file mode 100644 index 0000000..332415d --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list.tscn @@ -0,0 +1,87 @@ +[gd_scene load_steps=8 format=3 uid="uid://mbjdav5oqves"] + +[ext_resource type="Script" uid="uid://c84cxry3t35ny" path="res://addons/phantom_camera/scripts/panel/viewfinder/host_list.gd" id="1_h6ayt"] +[ext_resource type="Texture2D" uid="uid://5fatldiu7dd5" path="res://addons/phantom_camera/icons/phantom_camera_host.svg" id="1_xlgqb"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_w002y"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kq7gm"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.960784, 0.960784, 0.960784, 1) +corner_radius_top_right = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ynag5"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_right = 6 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q2svd"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e0jvt"] +content_margin_left = 0.0 +content_margin_top = 8.0 +content_margin_right = 0.0 +content_margin_bottom = 8.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 10 + +[node name="PCamHostList" type="VBoxContainer"] +anchors_preset = 9 +anchor_bottom = 1.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme_override_constants/separation = -2 +alignment = 2 +script = ExtResource("1_h6ayt") + +[node name="HostListButton" type="Button" parent="."] +unique_name_in_owner = true +custom_minimum_size = Vector2(40, 40) +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_colors/icon_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +theme_override_colors/icon_hover_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +theme_override_styles/focus = SubResource("StyleBoxEmpty_w002y") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_kq7gm") +theme_override_styles/hover = SubResource("StyleBoxFlat_ynag5") +theme_override_styles/pressed = SubResource("StyleBoxFlat_kq7gm") +theme_override_styles/normal = SubResource("StyleBoxFlat_q2svd") +icon = ExtResource("1_xlgqb") +expand_icon = true + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_e0jvt") +horizontal_scroll_mode = 0 + +[node name="HostListContainer" type="VBoxContainer" parent="ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_constants/separation = 8 diff --git a/addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn new file mode 100644 index 0000000..9ce67e5 --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=10 format=3 uid="uid://btn6jgv0vix7"] + +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="1_anjxo"] +[ext_resource type="Theme" uid="uid://bhppejri5dbsf" path="res://addons/phantom_camera/themes/theme.tres" id="1_wql5t"] +[ext_resource type="Texture2D" uid="uid://rghrkoqrm2ig" path="res://addons/phantom_camera/icons/viewfinder/Select.svg" id="2_71b6g"] +[ext_resource type="ButtonGroup" uid="uid://dfu0b8jbtyr1n" path="res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres" id="3_06a0y"] +[ext_resource type="Script" uid="uid://bv24ubx8mutw7" path="res://addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd" id="3_a5o8b"] +[ext_resource type="Texture2D" uid="uid://cjlv0bg7byjx0" path="res://addons/phantom_camera/icons/warning.svg" id="3_qgpy7"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0rxfi"] +content_margin_right = 6.0 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_llqnh"] + +[sub_resource type="Theme" id="Theme_7h15c"] +Button/colors/icon_hover_color = Color(0.960784, 0.960784, 0.960784, 1) +Button/colors/icon_hover_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/icon_normal_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/icon_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/constants/icon_max_width = 20 +Button/styles/focus = SubResource("StyleBoxEmpty_llqnh") + +[node name="HostListItem" type="PanelContainer"] +offset_right = 229.0 +offset_bottom = 34.0 +theme_override_styles/panel = SubResource("StyleBoxEmpty_0rxfi") +script = ExtResource("3_a5o8b") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +theme_override_constants/separation = 2 + +[node name="SelectPCamHost" type="Button" parent="HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 4 +tooltip_text = "Select the Phantom Camera Host node from the scene hierarchy" +focus_mode = 0 +theme = SubResource("Theme_7h15c") +icon = ExtResource("2_71b6g") +flat = true + +[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 8 + +[node name="ErrorPCamHost" type="TextureRect" parent="HBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(18, 18) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +tooltip_text = "This Phantom Camera Host node will not affect a Camera node. +See the warning in the Scene Tree for more information." +texture = ExtResource("3_qgpy7") +expand_mode = 1 + +[node name="SwitchPCamHost" type="Button" parent="HBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(40, 0) +layout_mode = 2 +tooltip_text = "Change the viewfinder's camera to the camera of this Phantom Camera Host" +theme = ExtResource("1_wql5t") +theme_override_fonts/font = ExtResource("1_anjxo") +theme_override_font_sizes/font_size = 18 +toggle_mode = true +button_group = ExtResource("3_06a0y") +text = "{ PCamHostName }" diff --git a/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres new file mode 100644 index 0000000..64c4600 --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres @@ -0,0 +1,3 @@ +[gd_resource type="ButtonGroup" format=3 uid="uid://dfu0b8jbtyr1n"] + +[resource] diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd new file mode 100644 index 0000000..27e7eed --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd @@ -0,0 +1,84 @@ +@tool +extends EditorNode3DGizmo + +#var pcam_3d: PhantomCamera3D + +func _redraw() -> void: + clear() + + var icon: Material = get_plugin().get_material(get_plugin().get_name(), self) + add_unscaled_billboard(icon, 0.035) + + var pcam_3d: PhantomCamera3D = get_node_3d() + +# if pcam_3d.is_following(): +# _draw_target(pcam_3d, pcam_3d.get_follow_target_position(), "follow_target") +# if pcam_3d.is_looking_at(): +# _draw_target(pcam_3d, pcam_3d.get_look_at_target_position(), "look_at_target") + + if pcam_3d.is_active(): return + + var frustum_lines: PackedVector3Array = PackedVector3Array() + var height: float = 0.25 + var width: float = height * 1.25 + var forward: float = height * -1.5 + + # Trapezoid + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(-width, height, forward)) + + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(width, height, forward)) + + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(-width, -height, forward)) + + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(width, -height, forward)) + + ####### + # Frame + ####### + ## Left + frustum_lines.push_back(Vector3(-width, height, forward)) + frustum_lines.push_back(Vector3(-width, -height, forward)) + + ## Bottom + frustum_lines.push_back(Vector3(-width, -height, forward)) + frustum_lines.push_back(Vector3(width, -height, forward)) + + ## Right + frustum_lines.push_back(Vector3(width, -height, forward)) + frustum_lines.push_back(Vector3(width, height, forward)) + + ## Top + frustum_lines.push_back(Vector3(width, height, forward)) + frustum_lines.push_back(Vector3(-width, height, forward)) + + ############## + # Up Direction + ############## + var up_height: float = height + 0.15 + var up_width: float = width / 3 + + ## Left + frustum_lines.push_back(Vector3(0, up_height, forward)) + frustum_lines.push_back(Vector3(-up_width, height, forward)) + + ## Right + frustum_lines.push_back(Vector3(0, up_height, forward)) + frustum_lines.push_back(Vector3(up_width, height, forward)) + + var frustum_material: StandardMaterial3D = get_plugin().get_material("frustum", self) + add_lines(frustum_lines, frustum_material, false) + + +func _draw_target(pcam_3d: Node3D, target_position: Vector3, type: String) -> void: + var target_lines: PackedVector3Array = PackedVector3Array() + var direction: Vector3 = target_position - pcam_3d.global_position + var end_position: Vector3 = pcam_3d.global_basis.z * direction + + target_lines.push_back(Vector3.ZERO) + target_lines.push_back(end_position) + var target_material: StandardMaterial3D = get_plugin().get_material(type, self) + add_lines(target_lines, target_material, false) diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd.uid b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd.uid new file mode 100644 index 0000000..564e0cf --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd.uid @@ -0,0 +1 @@ +uid://cyr6fgximfw6q diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd new file mode 100644 index 0000000..2caf713 --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd @@ -0,0 +1,37 @@ +@tool +extends EditorNode3DGizmoPlugin + +const PhantomCamera3DNode: Script = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd") +const PhantomCamera3DGizmo: Script = preload("res://addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd") +const _icon_texture: Texture2D = preload("res://addons/phantom_camera/icons/phantom_camera_gizmo.svg") +var _gizmo_name: String = "PhantomCamera3D" + +var gizmo_name: String: set = set_gizmo_name +var _gizmo_icon: Texture2D +var _gizmo_spatial_script: Script = PhantomCamera3DNode + + +func set_gizmo_name(name: String) -> void: + _gizmo_name = name + + +func _get_gizmo_name() -> String: + return _gizmo_name + + +func _has_gizmo(spatial: Node3D) -> bool: + return spatial is PhantomCamera3D + + +func _init() -> void: + create_icon_material(gizmo_name, _icon_texture, false, Color.WHITE) + create_material("frustum", Color8(252, 127, 127, 255)) + create_material("follow_target", Color8(185, 58, 89)) + create_material("look_at_target", Color8(61, 207, 225)) + + +func _create_gizmo(for_node_3d: Node3D) -> EditorNode3DGizmo: + if for_node_3d is PhantomCamera3DNode: + return PhantomCamera3DGizmo.new() + else: + return null diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd.uid b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd.uid new file mode 100644 index 0000000..ce528d7 --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd.uid @@ -0,0 +1 @@ +uid://bkevga3bx4rfj diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd new file mode 100644 index 0000000..3dd4d3e --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd @@ -0,0 +1,29 @@ +extends EditorNode3DGizmoPlugin + +var _spatial_script: Script = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd") +var _gizmo_icon: Texture2D = preload("res://addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg") + +var _gizmo_name: StringName = "PhantomCameraNoiseEmitter" + +func _init() -> void: + create_material("main", Color8(252, 127, 127, 255)) + create_handle_material("handles") + create_icon_material(_gizmo_name, _gizmo_icon, false, Color.WHITE) + + +func _has_gizmo(node: Node3D): + return node.get_script() == _spatial_script + + +func _get_gizmo_name() -> String: + return _gizmo_name + + +func _redraw(gizmo: EditorNode3DGizmo): + gizmo.clear() + + var icon: Material = get_material(_gizmo_name, gizmo) + gizmo.add_unscaled_billboard(icon, 0.035) + + #var material = get_material("main", gizmo) + #gizmo.add_lines(_draw_frustum(), material) diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid new file mode 100644 index 0000000..2b93b6c --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid @@ -0,0 +1 @@ +uid://dddokcd2ug05i diff --git a/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs new file mode 100644 index 0000000..5005230 --- /dev/null +++ b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs @@ -0,0 +1,36 @@ +using System.Linq; +using Godot; + +#nullable enable + +namespace PhantomCamera.Manager; + +public static class PhantomCameraManager +{ + private static GodotObject? _instance; + + public static GodotObject Instance => _instance ??= Engine.GetSingleton("PhantomCameraManager"); + + public static PhantomCamera2D[] PhantomCamera2Ds => + Instance.Call(MethodName.GetPhantomCamera2Ds).AsGodotArray() + .Select(node => new PhantomCamera2D(node)).ToArray(); + + public static PhantomCamera3D[] PhantomCamera3Ds => + Instance.Call(MethodName.GetPhantomCamera3Ds).AsGodotArray() + .Select(node => new PhantomCamera3D(node)).ToArray(); + + public static PhantomCameraHost[] PhantomCameraHosts => + Instance.Call(MethodName.GetPhantomCameraHosts).AsGodotArray() + .Select(node => new PhantomCameraHost(node)).ToArray(); + + public static PhantomCamera2D[] GetPhantomCamera2Ds() => PhantomCamera2Ds; + public static PhantomCamera3D[] GetPhantomCamera3Ds() => PhantomCamera3Ds; + public static PhantomCameraHost[] GetPhantomCameraHosts() => PhantomCameraHosts; + + public static class MethodName + { + public const string GetPhantomCamera2Ds = "get_phantom_camera_2ds"; + public const string GetPhantomCamera3Ds = "get_phantom_camera_3ds"; + public const string GetPhantomCameraHosts = "get_phantom_camera_hosts"; + } +} diff --git a/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs.uid b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs.uid new file mode 100644 index 0000000..cdf7f4e --- /dev/null +++ b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs.uid @@ -0,0 +1 @@ +uid://vtj8iqx4bp43 diff --git a/addons/phantom_camera/scripts/panel/editor.gd b/addons/phantom_camera/scripts/panel/editor.gd new file mode 100644 index 0000000..a10018c --- /dev/null +++ b/addons/phantom_camera/scripts/panel/editor.gd @@ -0,0 +1,23 @@ +@tool +extends VBoxContainer + +#region Onready + +@onready var updater: Control = %UpdateButton +@onready var viewfinder: Control = %ViewfinderPanel + +#endregion + +#region Public Variables + +var editor_plugin: EditorPlugin + +#endregion + + +#region Private Functions + +func _ready(): + updater.editor_plugin = editor_plugin + +#endregion diff --git a/addons/phantom_camera/scripts/panel/editor.gd.uid b/addons/phantom_camera/scripts/panel/editor.gd.uid new file mode 100644 index 0000000..6be368c --- /dev/null +++ b/addons/phantom_camera/scripts/panel/editor.gd.uid @@ -0,0 +1 @@ +uid://cgfwg3paxkj2x diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd new file mode 100644 index 0000000..662e598 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd @@ -0,0 +1,112 @@ +@tool +extends VBoxContainer + +#region Constants + +const _constants := preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") +const _host_list_item: PackedScene = preload("res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn") + +#endregion + +signal pcam_host_removed(pcam_host: PhantomCameraHost) + +@onready var _host_list_button: Button = %HostListButton +@onready var _host_list_scroll_container: ScrollContainer = %ScrollContainer +@onready var _host_list_item_container: VBoxContainer = %HostListContainer + +var _host_list_open: bool = false + +var _bottom_offset_value: float + +var _pcam_host_list: Array[PhantomCameraHost] +var _pcam_manager: Node + +var _viewfinder_panel: Control + +#region Private Functions + +func _ready() -> void: + _host_list_button.pressed.connect(_host_list_button_pressed) + if Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): + _pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + _pcam_manager.pcam_host_removed_from_scene.connect(_remove_pcam_host) + + if not get_parent() is Control: return # To prevent errors when opening the scene on its own + _viewfinder_panel = get_parent() + _viewfinder_panel.resized.connect(_set_offset_top) + + _host_list_item_container.resized.connect(_set_offset_top) + + +func _set_offset_top() -> void: + offset_top = _set_host_list_size() + + +func _host_list_button_pressed() -> void: + _host_list_open = !_host_list_open + + var tween: Tween = create_tween() + var max_duration: float = 0.6 + + # 300 being the minimum size of the viewfinder's height + var duration: float = clampf( + max_duration / (300 / _host_list_item_container.size.y), + 0.3, + max_duration) + + tween.tween_property(self, "offset_top", _set_host_list_size(), duration)\ + .set_ease(Tween.EASE_OUT)\ + .set_trans(Tween.TRANS_QUINT) + + +func _set_host_list_size() -> float: + if not _host_list_open: + return clampf( + _viewfinder_panel.size.y - \ + _host_list_item_container.size.y - \ + _host_list_button.size.y - 20, + 0, + INF + ) + else: + return (_viewfinder_panel.size.y - _host_list_button.size.y / 2) + + +func _remove_pcam_host(pcam_host: PhantomCameraHost) -> void: + if _pcam_host_list.has(pcam_host): + _pcam_host_list.erase(pcam_host) + + var freed_pcam_host: Control + for host_list_item_instance in _host_list_item_container.get_children(): + if not host_list_item_instance.pcam_host == pcam_host: continue + freed_pcam_host = host_list_item_instance + host_list_item_instance.queue_free() + +#endregion + +#region Public Functions + +func add_pcam_host(pcam_host: PhantomCameraHost, is_default: bool) -> void: + if _pcam_host_list.has(pcam_host): return + + _pcam_host_list.append(pcam_host) + + var host_list_item_instance: PanelContainer = _host_list_item.instantiate() + var switch_pcam_host_button: Button = host_list_item_instance.get_node("%SwitchPCamHost") + if is_default: switch_pcam_host_button.button_pressed = true + + if not pcam_host.tree_exiting.is_connected(_remove_pcam_host): + pcam_host.tree_exiting.connect(_remove_pcam_host.bind(pcam_host)) + + host_list_item_instance.pcam_host = pcam_host + + _host_list_item_container.add_child(host_list_item_instance) + + +func clear_pcam_host_list() -> void: + _pcam_host_list.clear() + + for host_list_item_instance in _host_list_item_container.get_children(): + host_list_item_instance.queue_free() + +#endregion diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd.uid b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd.uid new file mode 100644 index 0000000..6923d3e --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd.uid @@ -0,0 +1 @@ +uid://c84cxry3t35ny diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd new file mode 100644 index 0000000..5707974 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd @@ -0,0 +1,58 @@ +@tool +extends Control + +const button_group_resource: ButtonGroup = preload("res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres") +const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +@onready var select_pcam_host: Button = %SelectPCamHost +@onready var switch_pcam_host: Button = %SwitchPCamHost + +var pcam_host: PhantomCameraHost: + set(value): + pcam_host = value + if not is_instance_valid(value): return + if not pcam_host.renamed.is_connected(_rename_pcam_host): + pcam_host.renamed.connect(_rename_pcam_host) + pcam_host.has_error.connect(_pcam_host_has_error) + get: + return pcam_host + +var _pcam_manager: Node + +#region Private fucntions + +func _ready() -> void: + switch_pcam_host.button_group = button_group_resource + select_pcam_host.pressed.connect(_select_pcam) + switch_pcam_host.pressed.connect(_switch_pcam_host) + + if not is_instance_valid(pcam_host): return + switch_pcam_host.text = pcam_host.name + + _pcam_host_has_error() + + +func _pcam_host_has_error() -> void: + if pcam_host.show_warning: + %ErrorPCamHost.visible = true + else: + %ErrorPCamHost.visible = false + + +func _rename_pcam_host() -> void: + switch_pcam_host.text = pcam_host.name + + +func _select_pcam() -> void: + EditorInterface.get_selection().clear() + EditorInterface.get_selection().add_node(pcam_host) + + +func _switch_pcam_host() -> void: + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + if not is_instance_valid(_pcam_manager): + _pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + + _pcam_manager.viewfinder_pcam_host_switch.emit(pcam_host) + +#endregion diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd.uid b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd.uid new file mode 100644 index 0000000..9df2919 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd.uid @@ -0,0 +1 @@ +uid://bv24ubx8mutw7 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs new file mode 100644 index 0000000..267adf0 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs @@ -0,0 +1,253 @@ +using Godot; +using PhantomCamera.Noise; + +#nullable enable + +namespace PhantomCamera; + +public enum InactiveUpdateMode +{ + Always, + Never +} + +public abstract class PhantomCamera +{ + protected readonly GodotObject Node; + + public delegate void BecameActiveEventHandler(); + public delegate void BecameInactiveEventHandler(); + public delegate void FollowTargetChangedEventHandler(); + public delegate void DeadZoneChangedEventHandler(); + public delegate void TweenStartedEventHandler(); + public delegate void IsTweeningEventHandler(); + public delegate void TweenCompletedEventHandler(); + + public event BecameActiveEventHandler? BecameActive; + public event BecameInactiveEventHandler? BecameInactive; + public event FollowTargetChangedEventHandler? FollowTargetChanged; + public event DeadZoneChangedEventHandler? DeadZoneChanged; + public event TweenStartedEventHandler? TweenStarted; + public event IsTweeningEventHandler? IsTweening; + public event TweenCompletedEventHandler? TweenCompleted; + + private readonly Callable _callableBecameActive; + private readonly Callable _callableBecameInactive; + private readonly Callable _callableFollowTargetChanged; + private readonly Callable _callableDeadZoneChanged; + private readonly Callable _callableTweenStarted; + private readonly Callable _callableIsTweening; + private readonly Callable _callableTweenCompleted; + + public int Priority + { + get => (int)Node.Call(MethodName.GetPriority); + set => Node.Call(MethodName.SetPriority, value); + } + + public bool IsActive => (bool)Node.Call(MethodName.IsActive); + + public bool FollowDamping + { + get => (bool)Node.Call(MethodName.GetFollowDamping); + set => Node.Call(MethodName.SetFollowDamping, value); + } + + public bool IsFollowing => (bool)Node.Call(PhantomCamera.MethodName.IsFollowing); + + public float DeadZoneWidth + { + get => (float)Node.Get(PropertyName.DeadZoneWidth); + set => Node.Set(PropertyName.DeadZoneWidth, value); + } + + public float DeadZoneHeight + { + get => (float)Node.Get(PropertyName.DeadZoneHeight); + set => Node.Set(PropertyName.DeadZoneHeight, value); + } + + public PhantomCameraTween TweenResource + { + get => new((Resource)Node.Call(MethodName.GetTweenResource)); + set => Node.Call(MethodName.SetTweenResource, (GodotObject)value.Resource); + } + + public bool TweenSkip + { + get => (bool)Node.Call(MethodName.GetTweenSkip); + set => Node.Call(MethodName.SetTweenSkip, value); + } + + public float TweenDuration + { + get => (float)Node.Call(MethodName.GetTweenDuration); + set => Node.Call(MethodName.SetTweenDuration, value); + } + + public TransitionType TweenTransition + { + get => (TransitionType)(int)Node.Call(MethodName.GetTweenTransition); + set => Node.Call(MethodName.SetTweenTransition, (int)value); + } + + public EaseType TweenEase + { + get => (EaseType)(int)Node.Call(MethodName.GetTweenEase); + set => Node.Call(MethodName.SetTweenEase, (int)value); + } + + public bool TweenOnLoad + { + get => (bool)Node.Call(MethodName.GetTweenOnLoad); + set => Node.Call(MethodName.SetTweenOnLoad, value); + } + + public InactiveUpdateMode InactiveUpdateMode + { + get => (InactiveUpdateMode)(int)Node.Call(MethodName.GetInactiveUpdateMode); + set => Node.Call(MethodName.SetInactiveUpdateMode, (int)value); + } + + public int HostLayers + { + get => (int)Node.Call(MethodName.GetHostLayers); + set => Node.Call(MethodName.SetHostLayers, value); + } + + public int NoiseEmitterLayer + { + get => (int)Node.Call(MethodName.GetNoiseEmitterLayer); + set => Node.Call(MethodName.SetNoiseEmitterLayer, value); + } + + public void TeleportPosition() + { + Node.Call(MethodName.TeleportPosition); + } + + public void SetHostLayersValue(int layer, bool enabled) + { + Node.Call(MethodName.SetHostLayersValue, layer, enabled); + } + + protected PhantomCamera(GodotObject phantomCameraNode) + { + Node = phantomCameraNode; + + _callableBecameActive = Callable.From(() => BecameActive?.Invoke()); + _callableBecameInactive = Callable.From(() => BecameInactive?.Invoke()); + _callableFollowTargetChanged = Callable.From(() => FollowTargetChanged?.Invoke()); + _callableDeadZoneChanged = Callable.From(() => DeadZoneChanged?.Invoke()); + _callableTweenStarted = Callable.From(() => TweenStarted?.Invoke()); + _callableIsTweening = Callable.From(() => IsTweening?.Invoke()); + _callableTweenCompleted = Callable.From(() => TweenCompleted?.Invoke()); + + Node.Connect(SignalName.BecameActive, _callableBecameActive); + Node.Connect(SignalName.BecameInactive, _callableBecameInactive); + Node.Connect(SignalName.FollowTargetChanged, _callableFollowTargetChanged); + Node.Connect(SignalName.DeadZoneChanged, _callableDeadZoneChanged); + Node.Connect(SignalName.TweenStarted, _callableTweenStarted); + Node.Connect(SignalName.IsTweening, _callableIsTweening); + Node.Connect(SignalName.TweenCompleted, _callableTweenCompleted); + } + + ~PhantomCamera() + { + Node.Disconnect(SignalName.BecameActive, _callableBecameActive); + Node.Disconnect(SignalName.BecameInactive, _callableBecameInactive); + Node.Disconnect(SignalName.FollowTargetChanged, _callableFollowTargetChanged); + Node.Disconnect(SignalName.DeadZoneChanged, _callableDeadZoneChanged); + Node.Disconnect(SignalName.TweenStarted, _callableTweenStarted); + Node.Disconnect(SignalName.IsTweening, _callableIsTweening); + Node.Disconnect(SignalName.TweenCompleted, _callableTweenCompleted); + } + + public static class MethodName + { + public const string GetFollowMode = "get_follow_mode"; + public const string IsActive = "is_active"; + + public const string GetPriority = "get_priority"; + public const string SetPriority = "set_priority"; + + public const string IsFollowing = "is_following"; + + public const string GetFollowTarget = "get_follow_target"; + public const string SetFollowTarget = "set_follow_target"; + + public const string GetFollowTargets = "get_follow_targets"; + public const string SetFollowTargets = "set_follow_targets"; + + public const string TeleportPosition = "teleport_position"; + + public const string AppendFollowTargets = "append_follow_targets"; + public const string AppendFollowTargetsArray = "append_follow_targets_array"; + public const string EraseFollowTargets = "erase_follow_targets"; + + public const string GetFollowPath = "get_follow_path"; + public const string SetFollowPath = "set_follow_path"; + + public const string GetFollowOffset = "get_follow_offset"; + public const string SetFollowOffset = "set_follow_offset"; + + public const string GetFollowDamping = "get_follow_damping"; + public const string SetFollowDamping = "set_follow_damping"; + + public const string GetFollowDampingValue = "get_follow_damping_value"; + public const string SetFollowDampingValue = "set_follow_damping_value"; + + public const string GetFollowAxisLock = "get_follow_axis_lock"; + public const string SetFollowAxisLock = "set_follow_axis_lock"; + + public const string GetTweenResource = "get_tween_resource"; + public const string SetTweenResource = "set_tween_resource"; + + public const string GetTweenSkip = "get_tween_skip"; + public const string SetTweenSkip = "set_tween_skip"; + + public const string GetTweenDuration = "get_tween_duration"; + public const string SetTweenDuration = "set_tween_duration"; + + public const string GetTweenTransition = "get_tween_transition"; + public const string SetTweenTransition = "set_tween_transition"; + + public const string GetTweenEase = "get_tween_ease"; + public const string SetTweenEase = "set_tween_ease"; + + public const string GetTweenOnLoad = "get_tween_on_load"; + public const string SetTweenOnLoad = "set_tween_on_load"; + + public const string GetInactiveUpdateMode = "get_inactive_update_mode"; + public const string SetInactiveUpdateMode = "set_inactive_update_mode"; + + public const string GetHostLayers = "get_host_layers"; + public const string SetHostLayers = "set_host_layers"; + public const string SetHostLayersValue = "set_host_layers_value"; + + public const string GetNoiseEmitterLayer = "get_noise_emitter_layer"; + public const string SetNoiseEmitterLayer = "set_noise_emitter_layer"; + + public const string EmitNoise = "emit_noise"; + } + + public static class PropertyName + { + public const string DeadZoneWidth = "dead_zone_width"; + public const string DeadZoneHeight = "dead_zone_height"; + } + + public static class SignalName + { + public const string BecameActive = "became_active"; + public const string BecameInactive = "became_inactive"; + public const string FollowTargetChanged = "follow_target_changed"; + public const string DeadZoneChanged = "dead_zone_changed"; + public const string DeadZoneReached = "dead_zone_reached"; + public const string TweenStarted = "tween_started"; + public const string IsTweening = "is_tweening"; + public const string TweenCompleted = "tween_completed"; + public const string TweenInterrupted = "tween_interrupted"; + public const string NoiseEmitted = "noise_emitted"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs.uid new file mode 100644 index 0000000..856fbdb --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs.uid @@ -0,0 +1 @@ +uid://d3wh0457i0i3 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs new file mode 100644 index 0000000..20b3ba5 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs @@ -0,0 +1,351 @@ +using System.Linq; +using Godot; +using Godot.Collections; +using PhantomCamera.Noise; + +#nullable enable + +namespace PhantomCamera; + +public enum FollowMode2D +{ + None, + Glued, + Simple, + Group, + Path, + Framed +} + +public enum FollowLockAxis2D +{ + None, + X, + Y, + XY +} + +public static class PhantomCamera2DExtensions +{ + public static PhantomCamera2D AsPhantomCamera2D(this Node2D node2D) + { + return new PhantomCamera2D(node2D); + } + + public static PhantomCameraNoiseEmitter2D AsPhantomCameraNoiseEmitter2D(this Node2D node2D) + { + return new PhantomCameraNoiseEmitter2D(node2D); + } + + public static PhantomCameraNoise2D AsPhantomCameraNoise2D(this Resource resource) + { + return new PhantomCameraNoise2D(resource); + } +} + +public class PhantomCamera2D : PhantomCamera +{ + public Node2D Node2D => (Node2D)Node; + + public delegate void TweenInterruptedEventHandler(Node2D pCam); + public delegate void DeadZoneReachedEventHandler(Vector2 side); + public delegate void NoiseEmittedEventHandler(Transform2D output); + + public event TweenInterruptedEventHandler? TweenInterrupted; + public event DeadZoneReachedEventHandler? DeadZoneReached; + public event NoiseEmittedEventHandler? NoiseEmitted; + + private readonly Callable _callableTweenInterrupted; + private readonly Callable _callableDeadZoneReached; + private readonly Callable _callableNoiseEmitted; + + public Node2D FollowTarget + { + get => (Node2D)Node2D.Call(PhantomCamera.MethodName.GetFollowTarget); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowTarget, value); + } + + public Node2D[] FollowTargets + { + get => Node2D.Call(PhantomCamera.MethodName.GetFollowTargets).AsGodotArray().ToArray(); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowTargets, new Array(value)); + } + + public void AppendFollowTargets(Node2D target) => Node2D.Call(PhantomCamera.MethodName.AppendFollowTargets, target); + public void AppendFollowTargetsArray(Node2D[] targets) => Node2D.Call(PhantomCamera.MethodName.AppendFollowTargetsArray, targets); + public void EraseFollowTargets(Node2D target) => Node2D.Call(PhantomCamera.MethodName.EraseFollowTargets, target); + + public FollowMode2D FollowMode => (FollowMode2D)(int)Node.Call(PhantomCamera.MethodName.GetFollowMode); + + public Path2D FollowPath + { + get => (Path2D)Node2D.Call(PhantomCamera.MethodName.GetFollowPath); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowPath, value); + } + + public Vector2 FollowOffset + { + get => (Vector2)Node2D.Call(PhantomCamera.MethodName.GetFollowOffset); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowOffset, value); + } + + public Vector2 FollowDampingValue + { + get => (Vector2)Node2D.Call(PhantomCamera.MethodName.GetFollowDampingValue); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowDampingValue, value); + } + + public FollowLockAxis2D FollowAxisLock + { + get => (FollowLockAxis2D)(int)Node2D.Call(PhantomCamera.MethodName.GetFollowAxisLock); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowAxisLock, (int)value); + } + + public Vector2 Zoom + { + get => (Vector2)Node2D.Call(MethodName.GetZoom); + set => Node2D.Call(MethodName.SetZoom, value); + } + + public bool SnapToPixel + { + get => (bool)Node2D.Call(MethodName.GetSnapToPixel); + set => Node2D.Call(MethodName.SetSnapToPixel, value); + } + + public bool RotateWithTarget + { + get => (bool)Node2D.Call(MethodName.GetRotateWithTarget); + set => Node2D.Call(MethodName.SetRotateWithTarget, value); + } + + public float RotationOffset + { + get => (float)Node2D.Call(MethodName.GetRotationOffset); + set => Node2D.Call(MethodName.SetRotationOffset, value); + } + + public bool RotationDamping + { + get => (bool)Node2D.Call(MethodName.GetRotationDamping); + set => Node2D.Call(MethodName.SetRotationDamping, value); + } + + public float RotationDampingValue + { + get => (float)Node2D.Call(MethodName.GetRotationDampingValue); + set => Node2D.Call(MethodName.SetRotationDampingValue, value); + } + + public int LimitLeft + { + get => (int)Node2D.Call(MethodName.GetLimitLeft); + set => Node2D.Call(MethodName.SetLimitLeft, value); + } + + public int LimitTop + { + get => (int)Node2D.Call(MethodName.GetLimitTop); + set => Node2D.Call(MethodName.SetLimitTop, value); + } + + public int LimitRight + { + get => (int)Node2D.Call(MethodName.GetLimitRight); + set => Node2D.Call(MethodName.SetLimitRight, value); + } + + public int LimitBottom + { + get => (int)Node2D.Call(MethodName.GetLimitBottom); + set => Node2D.Call(MethodName.SetLimitBottom, value); + } + + public Vector4I LimitMargin + { + get => (Vector4I)Node2D.Call(MethodName.GetLimitMargin); + set => Node2D.Call(MethodName.SetLimitMargin, value); + } + + public bool AutoZoom + { + get => (bool)Node2D.Call(MethodName.GetAutoZoom); + set => Node2D.Call(MethodName.SetAutoZoom, value); + } + + public float AutoZoomMin + { + get => (float)Node2D.Call(MethodName.GetAutoZoomMin); + set => Node2D.Call(MethodName.SetAutoZoomMin, value); + } + + public float AutoZoomMax + { + get => (float)Node2D.Call(MethodName.GetAutoZoomMax); + set => Node2D.Call(MethodName.SetAutoZoomMax, value); + } + + public Vector4 AutoZoomMargin + { + get => (Vector4)Node2D.Call(MethodName.GetAutoZoomMargin); + set => Node2D.Call(MethodName.SetAutoZoomMargin, value); + } + + public bool DrawLimits + { + get => (bool)Node2D.Get(PropertyName.DrawLimits); + set => Node2D.Set(PropertyName.DrawLimits, value); + } + + public PhantomCameraNoise2D Noise + { + get => new((Resource)Node2D.Call(MethodName.GetNoise)); + set => Node2D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public void EmitNoise(Transform2D transform) => Node2D.Call(PhantomCamera.MethodName.EmitNoise, transform); + + public NodePath LimitTarget + { + get => (NodePath)Node2D.Call(MethodName.GetLimitTarget); + set => Node2D.Call(MethodName.SetLimitTarget, value); + } + + public static PhantomCamera2D FromScript(string path) => new(GD.Load(path).New().AsGodotObject()); + public static PhantomCamera2D FromScript(GDScript script) => new(script.New().AsGodotObject()); + + public PhantomCamera2D(GodotObject phantomCameraNode) : base(phantomCameraNode) + { + _callableTweenInterrupted = Callable.From(pCam => TweenInterrupted?.Invoke(pCam)); + _callableDeadZoneReached = Callable.From((Vector2 side) => DeadZoneReached?.Invoke(side)); + _callableNoiseEmitted = Callable.From((Transform2D output) => NoiseEmitted?.Invoke(output)); + + Node2D.Connect(SignalName.TweenInterrupted, _callableTweenInterrupted); + Node2D.Connect(SignalName.DeadZoneReached, _callableDeadZoneReached); + Node2D.Connect(SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + ~PhantomCamera2D() + { + Node2D.Disconnect(SignalName.TweenInterrupted, _callableTweenInterrupted); + Node2D.Disconnect(SignalName.DeadZoneReached, _callableDeadZoneReached); + Node2D.Disconnect(SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + public void SetLimitTarget(TileMap tileMap) + { + Node2D.Call(MethodName.SetLimitTarget, tileMap.GetPath()); + } + + public void SetLimitTarget(TileMapLayer tileMapLayer) + { + Node2D.Call(MethodName.SetLimitTarget, tileMapLayer.GetPath()); + } + + public void SetLimitTarget(CollisionShape2D shape2D) + { + Node2D.Call(MethodName.SetLimitTarget, shape2D.GetPath()); + } + + public LimitTargetQueryResult? GetLimitTarget() + { + var result = (NodePath)Node2D.Call(MethodName.GetLimitTarget); + return result.IsEmpty ? null : new LimitTargetQueryResult(Node2D.GetNode(result)); + } + + public void SetLimit(Side side, int value) + { + Node2D.Call(MethodName.SetLimit, (int)side, value); + } + + public int GetLimit(Side side) + { + return (int)Node2D.Call(MethodName.GetLimit, (int)side); + } + + public new static class MethodName + { + public const string GetZoom = "get_zoom"; + public const string SetZoom = "set_zoom"; + + public const string GetSnapToPixel = "get_snap_to_pixel"; + public const string SetSnapToPixel = "set_snap_to_pixel"; + + public const string GetRotateWithTarget = "get_rotate_with_target"; + public const string SetRotateWithTarget = "set_rotate_with_target"; + + public const string GetRotationOffset = "get_rotation_offset"; + public const string SetRotationOffset = "set_rotation_offset"; + + public const string GetRotationDamping = "get_rotation_damping"; + public const string SetRotationDamping = "set_rotation_damping"; + + public const string GetRotationDampingValue = "get_rotation_damping_value"; + public const string SetRotationDampingValue = "set_rotation_damping_value"; + + public const string GetLimit = "get_limit"; + public const string SetLimit = "set_limit"; + + public const string GetLimitLeft = "get_limit_left"; + public const string SetLimitLeft = "set_limit_left"; + + public const string GetLimitTop = "get_limit_top"; + public const string SetLimitTop = "set_limit_top"; + + public const string GetLimitRight = "get_limit_right"; + public const string SetLimitRight = "set_limit_right"; + + public const string GetLimitBottom = "get_limit_bottom"; + public const string SetLimitBottom = "set_limit_bottom"; + + public const string GetLimitTarget = "get_limit_target"; + public const string SetLimitTarget = "set_limit_target"; + + public const string GetLimitMargin = "get_limit_margin"; + public const string SetLimitMargin = "set_limit_margin"; + + public const string GetAutoZoom = "get_auto_zoom"; + public const string SetAutoZoom = "set_auto_zoom"; + + public const string GetAutoZoomMin = "get_auto_zoom_min"; + public const string SetAutoZoomMin = "set_auto_zoom_min"; + + public const string GetAutoZoomMax = "get_auto_zoom_max"; + public const string SetAutoZoomMax = "set_auto_zoom_max"; + + public const string GetAutoZoomMargin = "get_auto_zoom_margin"; + public const string SetAutoZoomMargin = "set_auto_zoom_margin"; + + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + } + + public new static class PropertyName + { + public const string DrawLimits = "draw_limits"; + } +} + +public class LimitTargetQueryResult(GodotObject godotObject) +{ + public bool IsTileMap => godotObject.IsClass("TileMap"); + + public bool IsTileMapLayer => godotObject.IsClass("TileMapLayer"); + + public bool IsCollisionShape2D => godotObject.IsClass("CollisionShape2D"); + + public TileMap? AsTileMap() + { + return IsTileMap ? (TileMap)godotObject : null; + } + + public TileMapLayer? AsTileMapLayer() + { + return IsTileMapLayer ? (TileMapLayer)godotObject : null; + } + + public CollisionShape2D? AsCollisionShape2D() + { + return IsCollisionShape2D ? (CollisionShape2D)godotObject : null; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs.uid new file mode 100644 index 0000000..8cc93f0 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs.uid @@ -0,0 +1 @@ +uid://c38e5qhsf3fk3 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs new file mode 100644 index 0000000..a3081d9 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs @@ -0,0 +1,493 @@ +using System.Linq; +using Godot; +using Godot.Collections; +using PhantomCamera.Noise; + +#nullable enable + +namespace PhantomCamera; + +public enum LookAtMode +{ + None, + Mimic, + Simple, + Group +} + +public enum FollowMode3D +{ + None, + Glued, + Simple, + Group, + Path, + Framed, + ThirdPerson +} + +public enum FollowLockAxis3D +{ + None, + X, + Y, + Z, + XY, + XZ, + YZ, + XYZ +} + +public static class PhantomCamera3DExtensions +{ + public static PhantomCamera3D AsPhantomCamera3D(this Node3D node3D) + { + return new PhantomCamera3D(node3D); + } + + public static PhantomCameraNoiseEmitter3D AsPhantomCameraNoiseEmitter3D(this Node3D node3D) + { + return new PhantomCameraNoiseEmitter3D(node3D); + } + + public static PhantomCameraNoise3D AsPhantomCameraNoise3D(this Resource resource) + { + return new PhantomCameraNoise3D(resource); + } + + public static Camera3DResource AsCamera3DResource(this Resource resource) + { + return new Camera3DResource(resource); + } + + public static Vector3 GetThirdPersonRotation(this PhantomCamera3D pCam3D) => + (Vector3)pCam3D.Node3D.Call(PhantomCamera3D.MethodName.GetThirdPersonRotation); + + public static void SetThirdPersonRotation(this PhantomCamera3D pCam3D, Vector3 rotation) => + pCam3D.Node3D.Call(PhantomCamera3D.MethodName.SetThirdPersonRotation, rotation); + + public static Vector3 GetThirdPersonRotationDegrees(this PhantomCamera3D pCam3D) => + (Vector3)pCam3D.Node3D.Call(PhantomCamera3D.MethodName.GetThirdPersonRotationDegrees); + + public static void SetThirdPersonDegrees(this PhantomCamera3D pCam3D, Vector3 rotation) => + pCam3D.Node3D.Call(PhantomCamera3D.MethodName.SetThirdPersonRotationDegrees, rotation); + + public static Quaternion GetThirdPersonQuaternion(this PhantomCamera3D pCam3D) => + (Quaternion)pCam3D.Node3D.Call(PhantomCamera3D.MethodName.GetThirdPersonQuaternion); + + public static void SetThirdPersonQuaternion(this PhantomCamera3D pCam3D, Quaternion quaternion) => + pCam3D.Node3D.Call(PhantomCamera3D.MethodName.SetThirdPersonQuaternion, quaternion); + +} + +public class PhantomCamera3D : PhantomCamera +{ + public Node3D Node3D => (Node3D)Node; + + public delegate void LookAtTargetChangedEventHandler(); + public delegate void DeadZoneReachedEventHandler(); + public delegate void Camera3DResourceChangedEventHandler(); + public delegate void Camera3DResourcePropertyChangedEventHandler(StringName property, Variant value); + public delegate void TweenInterruptedEventHandler(Node3D pCam); + public delegate void NoiseEmittedEventHandler(Transform3D output); + + public event LookAtTargetChangedEventHandler? LookAtTargetChanged; + public event DeadZoneReachedEventHandler? DeadZoneReached; + public event Camera3DResourceChangedEventHandler? Camera3DResourceChanged; + public event Camera3DResourcePropertyChangedEventHandler? Camera3DResourcePropertyChanged; + public event TweenInterruptedEventHandler? TweenInterrupted; + public event NoiseEmittedEventHandler? NoiseEmitted; + + private readonly Callable _callableLookAtTargetChanged; + private readonly Callable _callableDeadZoneReached; + private readonly Callable _callableCamera3DResourceChanged; + private readonly Callable _callableCamera3DResourcePropertyChanged; + private readonly Callable _callableTweenInterrupted; + private readonly Callable _callableNoiseEmitted; + + public Node3D FollowTarget + { + get => (Node3D)Node3D.Call(PhantomCamera.MethodName.GetFollowTarget); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowTarget, value); + } + + public Node3D[] FollowTargets + { + get => Node3D.Call(PhantomCamera.MethodName.GetFollowTargets).AsGodotArray().ToArray(); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowTargets, new Array(value)); + } + + public void AppendFollowTarget(Node3D target) => Node3D.Call(PhantomCamera.MethodName.AppendFollowTargets, target); + public void AppendFollowTargetArray(Node3D[] targets) => Node3D.Call(PhantomCamera.MethodName.AppendFollowTargetsArray, targets); + public void EraseFollowTarget(Node3D target) => Node3D.Call(PhantomCamera.MethodName.EraseFollowTargets, target); + + public FollowMode3D FollowMode => (FollowMode3D)(int)Node.Call(PhantomCamera.MethodName.GetFollowMode); + + public Path3D FollowPath + { + get => (Path3D)Node3D.Call(PhantomCamera.MethodName.GetFollowPath); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowPath, value); + } + + public Vector3 FollowOffset + { + get => (Vector3)Node3D.Call(PhantomCamera.MethodName.GetFollowOffset); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowOffset, value); + } + + public Vector3 FollowDampingValue + { + get => (Vector3)Node3D.Call(PhantomCamera.MethodName.GetFollowDampingValue); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowDampingValue, value); + } + + public FollowLockAxis3D FollowAxisLock + { + get => (FollowLockAxis3D)(int)Node3D.Call(PhantomCamera.MethodName.GetFollowAxisLock); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowAxisLock, (int)value); + } + + public LookAtMode LookAtMode => (LookAtMode)(int)Node3D.Call(MethodName.GetLookAtMode); + + public Camera3DResource Camera3DResource + { + get => new((Resource)Node3D.Call(MethodName.GetCamera3DResource)); + set => Node3D.Call(MethodName.SetCamera3DResource, value.Resource); + } + + public float SpringLength + { + get => (float)Node3D.Call(MethodName.GetSpringLength); + set => Node3D.Call(MethodName.SetSpringLength, value); + } + + public float VerticalRotationOffset + { + get => (float)Node3D.Call(MethodName.GetVerticalRotationOffset); + set => Node3D.Call(MethodName.SetVerticalRotationOffset, value); + } + + public float HorizontalRotationOffset + { + get => (float)Node3D.Call(MethodName.GetHorizontalRotationOffset); + set => Node3D.Call(MethodName.SetHorizontalRotationOffset, value); + } + + public float FollowDistance + { + get => (float)Node3D.Call(MethodName.GetFollowDistance); + set => Node3D.Call(MethodName.SetFollowDistance, value); + } + + public bool AutoFollowDistance + { + get => (bool)Node3D.Call(MethodName.GetAutoFollowDistance); + set => Node3D.Call(MethodName.SetAutoFollowDistance, value); + } + + public float AutoFollowDistanceMin + { + get => (float)Node3D.Call(MethodName.GetAutoFollowDistanceMin); + set => Node3D.Call(MethodName.SetAutoFollowDistanceMin, value); + } + + public float AutoFollowDistanceMax + { + get => (float)Node3D.Call(MethodName.GetAutoFollowDistanceMax); + set => Node3D.Call(MethodName.SetAutoFollowDistanceMax, value); + } + + public float AutoFollowDistanceDivisor + { + get => (float)Node3D.Call(MethodName.GetAutoFollowDistanceDivisor); + set => Node3D.Call(MethodName.SetAutoFollowDistanceDivisor, value); + } + + public Node3D LookAtTarget + { + get => (Node3D)Node3D.Call(MethodName.GetLookAtTarget); + set => Node3D.Call(MethodName.SetLookAtTarget, value); + } + + public Node3D[] LookAtTargets + { + get => Node3D.Call(MethodName.GetLookAtTargets).AsGodotArray().ToArray(); + set => Node3D.Call(MethodName.SetLookAtTargets, new Array(value)); + } + + public bool IsLooking => (bool)Node3D.Call(MethodName.IsLooking); + + public int CollisionMask + { + get => (int)Node3D.Call(MethodName.GetCollisionMask); + set => Node3D.Call(MethodName.SetCollisionMask, value); + } + + public void SetCollisionMaskValue(int maskLayer, bool enable) => + Node3D.Call(MethodName.SetCollisionMaskValue, maskLayer, enable); + + public Shape3D Shape + { + get => (Shape3D)Node3D.Call(MethodName.GetShape); + set => Node3D.Call(MethodName.SetShape, value); + } + + public float Margin + { + get => (float)Node3D.Call(MethodName.GetMargin); + set => Node3D.Call(MethodName.SetMargin, value); + } + + public Vector3 LookAtOffset + { + get => (Vector3)Node3D.Call(MethodName.GetLookAtOffset); + set => Node3D.Call(MethodName.SetLookAtOffset, value); + } + + public bool LookAtDamping + { + get => (bool)Node3D.Call(MethodName.GetLookAtDamping); + set => Node3D.Call(MethodName.SetLookAtDamping, value); + } + + public float LookAtDampingValue + { + get => (float)Node3D.Call(MethodName.GetLookAtDampingValue); + set => Node3D.Call(MethodName.SetLookAtDampingValue, value); + } + + public Node3D Up + { + get => (Node3D)Node3D.Call(MethodName.GetUp); + set => Node3D.Call(MethodName.SetUp, value); + } + + public Vector3 UpTarget + { + get => (Vector3)Node3D.Call(MethodName.GetUpTarget); + set => Node3D.Call(MethodName.SetUpTarget, value); + } + + public int CullMask + { + get => (int)Node3D.Call(MethodName.GetCullMask); + set => Node3D.Call(MethodName.SetCullMask, value); + } + + public float HOffset + { + get => (float)Node3D.Call(MethodName.GetHOffset); + set => Node3D.Call(MethodName.SetHOffset, value); + } + + public float VOffset + { + get => (float)Node3D.Call(MethodName.GetVOffset); + set => Node3D.Call(MethodName.SetVOffset, value); + } + + public ProjectionType Projection + { + get => (ProjectionType)(int)Node3D.Call(MethodName.GetProjection); + set => Node3D.Call(MethodName.SetProjection, (int)value); + } + + public float Fov + { + get => (float)Node3D.Call(MethodName.GetFov); + set => Node3D.Call(MethodName.SetFov, value); + } + + public float Size + { + get => (float)Node3D.Call(MethodName.GetSize); + set => Node3D.Call(MethodName.SetSize, value); + } + + public Vector2 FrustumOffset + { + get => (Vector2)Node3D.Call(MethodName.GetFrustumOffset); + set => Node3D.Call(MethodName.SetFrustumOffset, value); + } + + public float Far + { + get => (float)Node3D.Call(MethodName.GetFar); + set => Node3D.Call(MethodName.SetFar, value); + } + + public float Near + { + get => (float)Node3D.Call(MethodName.GetNear); + set => Node3D.Call(MethodName.SetNear, value); + } + + public Environment Environment + { + get => (Environment)Node3D.Call(MethodName.GetEnvironment); + set => Node3D.Call(MethodName.SetEnvironment, value); + } + + public CameraAttributes Attributes + { + get => (CameraAttributes)Node3D.Call(MethodName.GetAttributes); + set => Node3D.Call(MethodName.SetAttributes, value); + } + + public PhantomCameraNoise3D Noise + { + get => new((Resource)Node3D.Call(MethodName.GetNoise)); + set => Node3D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public void EmitNoise(Transform3D transform) => Node3D.Call(PhantomCamera.MethodName.EmitNoise, transform); + + public static PhantomCamera3D FromScript(string path) => new(GD.Load(path).New().AsGodotObject()); + public static PhantomCamera3D FromScript(GDScript script) => new(script.New().AsGodotObject()); + + public PhantomCamera3D(GodotObject phantomCamera3DNode) : base(phantomCamera3DNode) + { + _callableLookAtTargetChanged = Callable.From(() => LookAtTargetChanged?.Invoke()); + _callableDeadZoneReached = Callable.From(() => DeadZoneReached?.Invoke()); + _callableCamera3DResourceChanged = Callable.From(() => Camera3DResourceChanged?.Invoke()); + _callableCamera3DResourcePropertyChanged = Callable.From((StringName property, Variant value) => + Camera3DResourcePropertyChanged?.Invoke(property, value)); + _callableTweenInterrupted = Callable.From(pCam => TweenInterrupted?.Invoke(pCam)); + _callableNoiseEmitted = Callable.From((Transform3D output) => NoiseEmitted?.Invoke(output)); + + Node3D.Connect(SignalName.LookAtTargetChanged, _callableLookAtTargetChanged); + Node3D.Connect(PhantomCamera.SignalName.DeadZoneReached, _callableDeadZoneReached); + Node3D.Connect(SignalName.Camera3DResourceChanged, _callableCamera3DResourceChanged); + Node3D.Connect(SignalName.Camera3DResourcePropertyChanged, _callableCamera3DResourcePropertyChanged); + Node3D.Connect(PhantomCamera.SignalName.TweenInterrupted, _callableTweenInterrupted); + Node3D.Connect(PhantomCamera.SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + ~PhantomCamera3D() + { + Node3D.Disconnect(SignalName.LookAtTargetChanged, _callableLookAtTargetChanged); + Node3D.Disconnect(PhantomCamera.SignalName.DeadZoneReached, _callableDeadZoneReached); + Node3D.Disconnect(SignalName.Camera3DResourceChanged, _callableCamera3DResourceChanged); + Node3D.Disconnect(SignalName.Camera3DResourcePropertyChanged, _callableCamera3DResourcePropertyChanged); + Node3D.Disconnect(PhantomCamera.SignalName.TweenInterrupted, _callableTweenInterrupted); + Node3D.Disconnect(PhantomCamera.SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + public new static class MethodName + { + public const string GetLookAtMode = "get_look_at_mode"; + + public const string GetCamera3DResource = "get_camera_3d_resource"; + public const string SetCamera3DResource = "set_camera_3d_resource"; + + public const string GetThirdPersonRotation = "get_third_person_rotation"; + public const string SetThirdPersonRotation = "set_third_person_rotation"; + + public const string GetThirdPersonRotationDegrees = "get_third_person_rotation_degrees"; + public const string SetThirdPersonRotationDegrees = "set_third_person_rotation_degrees"; + + public const string GetThirdPersonQuaternion = "get_third_person_quaternion"; + public const string SetThirdPersonQuaternion = "set_third_person_quaternion"; + + public const string GetVerticalRotationOffset = "get_vertical_rotation_offset"; + public const string SetVerticalRotationOffset = "set_vertical_rotation_offset"; + + public const string GetHorizontalRotationOffset = "get_horizontal_rotation_offset"; + public const string SetHorizontalRotationOffset = "set_horizontal_rotation_offset"; + + public const string GetSpringLength = "get_spring_length"; + public const string SetSpringLength = "set_spring_length"; + + public const string GetFollowDistance = "get_follow_distance"; + public const string SetFollowDistance = "set_follow_distance"; + + public const string GetAutoFollowDistance = "get_auto_follow_distance"; + public const string SetAutoFollowDistance = "set_auto_follow_distance"; + + public const string GetAutoFollowDistanceMin = "get_auto_follow_distance_min"; + public const string SetAutoFollowDistanceMin = "set_auto_follow_distance_min"; + + public const string GetAutoFollowDistanceMax = "get_auto_follow_distance_max"; + public const string SetAutoFollowDistanceMax = "set_auto_follow_distance_max"; + + public const string GetAutoFollowDistanceDivisor = "get_auto_follow_distance_divisor"; + public const string SetAutoFollowDistanceDivisor = "set_auto_follow_distance_divisor"; + + public const string GetLookAtTarget = "get_look_at_target"; + public const string SetLookAtTarget = "set_look_at_target"; + + public const string GetLookAtTargets = "get_look_at_targets"; + public const string SetLookAtTargets = "set_look_at_targets"; + + public const string IsLooking = "is_looking"; + + public const string GetUp = "get_up"; + public const string SetUp = "set_up"; + + public const string GetUpTarget = "get_up_target"; + public const string SetUpTarget = "set_up_target"; + + public const string GetCollisionMask = "get_collision_mask"; + public const string SetCollisionMask = "set_collision_mask"; + + public const string SetCollisionMaskValue = "set_collision_mask_value"; + + public const string GetShape = "get_shape"; + public const string SetShape = "set_shape"; + + public const string GetMargin = "get_margin"; + public const string SetMargin = "set_margin"; + + public const string GetLookAtOffset = "get_look_at_offset"; + public const string SetLookAtOffset = "set_look_at_offset"; + + public const string GetLookAtDamping = "get_look_at_damping"; + public const string SetLookAtDamping = "set_look_at_damping"; + + public const string GetLookAtDampingValue = "get_look_at_damping_value"; + public const string SetLookAtDampingValue = "set_look_at_damping_value"; + + public const string GetCullMask = "get_cull_mask"; + public const string SetCullMask = "set_cull_mask"; + + public const string GetHOffset = "get_h_offset"; + public const string SetHOffset = "set_h_offset"; + + public const string GetVOffset = "get_v_offset"; + public const string SetVOffset = "set_v_offset"; + + public const string GetProjection = "get_projection"; + public const string SetProjection = "set_projection"; + + public const string GetFov = "get_fov"; + public const string SetFov = "set_fov"; + + public const string GetSize = "get_size"; + public const string SetSize = "set_size"; + + public const string GetFrustumOffset = "get_frustum_offset"; + public const string SetFrustumOffset = "set_frustum_offset"; + + public const string GetFar = "get_far"; + public const string SetFar = "set_far"; + + public const string GetNear = "get_near"; + public const string SetNear = "set_near"; + + public const string GetEnvironment = "get_environment"; + public const string SetEnvironment = "set_environment"; + + public const string GetAttributes = "get_attributes"; + public const string SetAttributes = "set_attributes"; + + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + } + + public new static class SignalName + { + public const string LookAtTargetChanged = "look_at_target_changed"; + public const string Camera3DResourceChanged = "camera_3d_resource_changed"; + public const string Camera3DResourcePropertyChanged = "camera_3d_resource_property_changed"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs.uid new file mode 100644 index 0000000..c1f0801 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs.uid @@ -0,0 +1 @@ +uid://bx3g7jxtwhi04 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs new file mode 100644 index 0000000..1e73b57 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs @@ -0,0 +1,83 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoiseEmitter2D(GodotObject node) +{ + public Node2D Node2D = (Node2D)node; + + public PhantomCameraNoise2D Noise + { + get => new((Resource)Node2D.Call(MethodName.GetNoise)); + set => Node2D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public bool Continuous + { + get => (bool)Node2D.Call(MethodName.GetContinuous); + set => Node2D.Call(MethodName.SetContinuous, value); + } + + public float GrowthTime + { + get => (float)Node2D.Call(MethodName.GetGrowthTime); + set => Node2D.Call(MethodName.SetGrowthTime, value); + } + + public float Duration + { + get => (float)Node2D.Call(MethodName.GetDuration); + set => Node2D.Call(MethodName.SetDuration, value); + } + + public float DecayTime + { + get => (float)Node2D.Call(MethodName.GetDecayTime); + set => Node2D.Call(MethodName.SetDecayTime, value); + } + + public int NoiseEmitterLayer + { + get => (int)Node2D.Call(MethodName.GetNoiseEmitterLayer); + set => Node2D.Call(MethodName.SetNoiseEmitterLayer, value); + } + + public void SetNoiseEmitterLayerValue(int layer, bool value) => + Node2D.Call(MethodName.SetNoiseEmitterLayerValue, layer, value); + + public void Emit() => Node2D.Call(MethodName.Emit); + + public bool IsEmitting() => (bool)Node2D.Call(MethodName.IsEmitting); + + public void Stop() => Node2D.Call(MethodName.Stop); + + public void Toggle() => Node2D.Call(MethodName.Toggle); + + public static class MethodName + { + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + + public const string GetContinuous = "get_continuous"; + public const string SetContinuous = "set_continuous"; + + public const string GetGrowthTime = "get_growth_time"; + public const string SetGrowthTime = "set_growth_time"; + + public const string GetDuration = "get_duration"; + public const string SetDuration = "set_duration"; + + public const string GetDecayTime = "get_decay_time"; + public const string SetDecayTime = "set_decay_time"; + + public const string GetNoiseEmitterLayer = "get_noise_emitter_layer"; + public const string SetNoiseEmitterLayer = "set_noise_emitter_layer"; + + public const string SetNoiseEmitterLayerValue = "set_noise_emitter_layer_value"; + + public const string Emit = "emit"; + public const string IsEmitting = "is_emitting"; + public const string Stop = "stop"; + public const string Toggle = "toggle"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs.uid new file mode 100644 index 0000000..4f35145 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs.uid @@ -0,0 +1 @@ +uid://btom8l3wlkn2j diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs new file mode 100644 index 0000000..18620b2 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs @@ -0,0 +1,83 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoiseEmitter3D(GodotObject node) +{ + public Node3D Node3D = (Node3D)node; + + public PhantomCameraNoise3D Noise + { + get => new((Resource)Node3D.Call(MethodName.GetNoise)); + set => Node3D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public bool Continuous + { + get => (bool)Node3D.Call(MethodName.GetContinuous); + set => Node3D.Call(MethodName.SetContinuous, value); + } + + public float GrowthTime + { + get => (float)Node3D.Call(MethodName.GetGrowthTime); + set => Node3D.Call(MethodName.SetGrowthTime, value); + } + + public float Duration + { + get => (float)Node3D.Call(MethodName.GetDuration); + set => Node3D.Call(MethodName.SetDuration, value); + } + + public float DecayTime + { + get => (float)Node3D.Call(MethodName.GetDecayTime); + set => Node3D.Call(MethodName.SetDecayTime, value); + } + + public int NoiseEmitterLayer + { + get => (int)Node3D.Call(MethodName.GetNoiseEmitterLayer); + set => Node3D.Call(MethodName.SetNoiseEmitterLayer, value); + } + + public void SetNoiseEmitterLayerValue(int layer, bool value) => + Node3D.Call(MethodName.SetNoiseEmitterLayerValue, layer, value); + + public void Emit() => Node3D.Call(MethodName.Emit); + + public bool IsEmitting() => (bool)Node3D.Call(MethodName.IsEmitting); + + public void Stop() => Node3D.Call(MethodName.Stop); + + public void Toggle() => Node3D.Call(MethodName.Toggle); + + public static class MethodName + { + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + + public const string GetContinuous = "get_continuous"; + public const string SetContinuous = "set_continuous"; + + public const string GetGrowthTime = "get_growth_time"; + public const string SetGrowthTime = "set_growth_time"; + + public const string GetDuration = "get_duration"; + public const string SetDuration = "set_duration"; + + public const string GetDecayTime = "get_decay_time"; + public const string SetDecayTime = "set_decay_time"; + + public const string GetNoiseEmitterLayer = "get_noise_emitter_layer"; + public const string SetNoiseEmitterLayer = "set_noise_emitter_layer"; + + public const string SetNoiseEmitterLayerValue = "set_noise_emitter_layer_value"; + + public const string Emit = "emit"; + public const string IsEmitting = "is_emitting"; + public const string Stop = "stop"; + public const string Toggle = "toggle"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs.uid new file mode 100644 index 0000000..bf32a5b --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs.uid @@ -0,0 +1 @@ +uid://buvda14filkjx diff --git a/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs new file mode 100644 index 0000000..be211bd --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs @@ -0,0 +1,128 @@ +using Godot; + +#nullable enable + +namespace PhantomCamera; + +public enum InterpolationMode +{ + Auto, + Idle, + Physics +} + +public static class PhantomCameraHostExtensions +{ + public static PhantomCameraHost AsPhantomCameraHost(this Node node) + { + return new PhantomCameraHost(node); + } +} + +public class PhantomCameraHost() +{ + public Node Node { get; } = null!; + + public PhantomCameraHost(Node node) : this() + { + Node = node; + + _callablePCamBecameActive = Callable.From(pCam => PCamBecameActive?.Invoke(pCam)); + _callablePCamBecameInactive = Callable.From(pCam => PCamBecameInactive?.Invoke(pCam)); + + Node.Connect(SignalName.PCamBecameActive, _callablePCamBecameActive); + Node.Connect(SignalName.PCamBecameInactive, _callablePCamBecameInactive); + } + + ~PhantomCameraHost() + { + Node.Disconnect(SignalName.PCamBecameActive, _callablePCamBecameActive); + Node.Disconnect(SignalName.PCamBecameInactive, _callablePCamBecameInactive); + } + + public delegate void PCamBecameActiveEventHandler(Node pCam); + public delegate void PCamBecameInactiveEventHandler(Node pCam); + + public event PCamBecameActiveEventHandler? PCamBecameActive; + public event PCamBecameInactiveEventHandler? PCamBecameInactive; + + + private readonly Callable _callablePCamBecameActive; + private readonly Callable _callablePCamBecameInactive; + // For when Godot becomes the minimum version + // public InterpolationMode InterpolationMode + // { + // get => (InterpolationMode)(int)Node.Call(MethodName.GetInterpolationMode); + // set => Node.Call(MethodName.SetInterpolationMode, (int)value); + // } + + public int HostLayers + { + get => (int)Node.Call(PhantomCamera.MethodName.GetHostLayers); + set => Node.Call(PhantomCamera.MethodName.SetHostLayers, value); + } + + public void SetHostLayersValue(int layer, bool value) => Node.Call(MethodName.SetHostLayersValue, layer, value); + + public Camera2D? Camera2D => (Camera2D?)Node.Get(PropertyName.Camera2D); + + public Camera3D? Camera3D => (Camera3D?)Node.Get(PropertyName.Camera3D); + + public InterpolationMode InterpolationMode + { + get => (InterpolationMode)(int)Node.Call(MethodName.GetInterpolationMode); + set => Node.Call(MethodName.SetInterpolationMode, (int)value); + } + + public bool TriggerPhantomCameraTween => (bool)Node.Call(MethodName.GetTriggerPhantomCameraTween); + + public ActivePhantomCameraQueryResult? GetActivePhantomCamera() + { + var result = Node.Call(MethodName.GetActivePhantomCamera); + return result.VariantType == Variant.Type.Nil ? null : new ActivePhantomCameraQueryResult(result.AsGodotObject()); + } + + public static class PropertyName + { + public const string Camera2D = "camera_2d"; + public const string Camera3D = "camera_3d"; + } + + public static class MethodName + { + public const string GetActivePhantomCamera = "get_active_pcam"; + public const string GetTriggerPhantomCameraTween = "get_trigger_pcam_tween"; + + public const string GetInterpolationMode = "get_interpolation_mode"; + public const string SetInterpolationMode = "set_interpolation_mode"; + + public const string SetHostLayersValue = "set_host_layers_value"; + } + + public static class SignalName + { + public const string PCamBecameActive = "pcam_became_active"; + public const string PCamBecameInactive = "pcam_became_inactive"; + } +} + +public class ActivePhantomCameraQueryResult(GodotObject godotObject) +{ + public bool Is2D => godotObject.IsClass("Node2D") || ((Node)godotObject).Name.ToString().Contains("PhantomCamera2D") + || ((Node)godotObject).Name.ToString().Contains("PCam2D") + || ((Node)godotObject).Name.ToString().Contains("2D"); + + public bool Is3D => godotObject.IsClass("Node3D") || ((Node)godotObject).Name.ToString().Contains("PhantomCamera3D") + || ((Node)godotObject).Name.ToString().Contains("PCam3D") + || ((Node)godotObject).Name.ToString().Contains("3D"); + + public PhantomCamera2D? AsPhantomCamera2D() + { + return Is2D ? new PhantomCamera2D(godotObject) : null; + } + + public PhantomCamera3D? AsPhantomCamera3D() + { + return Is3D ? new PhantomCamera3D(godotObject) : null; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs.uid b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs.uid new file mode 100644 index 0000000..ad4b4f5 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs.uid @@ -0,0 +1 @@ +uid://cr8brwrls2nn3 diff --git a/addons/phantom_camera/scripts/resources/Camera3DResource.cs b/addons/phantom_camera/scripts/resources/Camera3DResource.cs new file mode 100644 index 0000000..7bd00b5 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/Camera3DResource.cs @@ -0,0 +1,117 @@ +using Godot; + +namespace PhantomCamera; + +public enum KeepAspect +{ + KeepWidth, + KeepHeight +} + +public enum ProjectionType +{ + Perspective, + Orthogonal, + Frustum +} + +public class Camera3DResource(Resource resource) +{ + public readonly Resource Resource = resource; + + public KeepAspect KeepAspect + { + get => (KeepAspect)(int)Resource.Call(MethodName.GetKeepAspect); + set => Resource.Call(MethodName.SetKeepAspect, (int)value); + } + + public int CullMask + { + get => (int)Resource.Call(MethodName.GetCullMask); + set => Resource.Call(MethodName.SetCullMask, value); + } + + public void SetCullMaskValue(int layer, bool value) => Resource.Call(MethodName.SetCullMaskValue, layer, value); + + public float HOffset + { + get => (float)Resource.Call(MethodName.GetHOffset); + set => Resource.Call(MethodName.SetHOffset, value); + } + + public float VOffset + { + get => (float)Resource.Call(MethodName.GetVOffset); + set => Resource.Call(MethodName.SetVOffset, value); + } + + public ProjectionType Projection + { + get => (ProjectionType)(int)Resource.Call(MethodName.GetProjection); + set => Resource.Call(MethodName.SetProjection, (int)value); + } + + public float Fov + { + get => (float)Resource.Call(MethodName.GetFov); + set => Resource.Call(MethodName.SetFov, Mathf.Clamp(value, 1, 179)); + } + + public float Size + { + get => (float)Resource.Call(MethodName.GetSize); + set => Resource.Call(MethodName.SetSize, Mathf.Clamp(value, 0.001f, float.PositiveInfinity)); + } + + public Vector2 FrustumOffset + { + get => (Vector2)Resource.Call(MethodName.GetFrustumOffset); + set => Resource.Call(MethodName.SetFrustumOffset, value); + } + + public float Near + { + get => (float)Resource.Call(MethodName.GetNear); + set => Resource.Call(MethodName.SetNear, Mathf.Clamp(value, 0.001f, float.PositiveInfinity)); + } + + public float Far + { + get => (float)Resource.Call(MethodName.GetFar); + set => Resource.Call(MethodName.SetFar, Mathf.Clamp(value, 0.01f, float.PositiveInfinity)); + } + + public static class MethodName + { + public const string GetKeepAspect = "get_keep_aspect"; + public const string SetKeepAspect = "set_keep_aspect"; + + public const string GetCullMask = "get_cull_mask"; + public const string SetCullMask = "set_cull_mask"; + public const string SetCullMaskValue = "set_cull_mask_value"; + + public const string GetHOffset = "get_h_offset"; + public const string SetHOffset = "set_h_offset"; + + public const string GetVOffset = "get_v_offset"; + public const string SetVOffset = "set_v_offset"; + + public const string GetProjection = "get_projection"; + public const string SetProjection = "set_projection"; + + public const string GetFov = "get_fov"; + public const string SetFov = "set_fov"; + + public const string GetSize = "get_size"; + public const string SetSize = "set_size"; + + public const string GetFrustumOffset = "get_frustum_offset"; + public const string SetFrustumOffset = "set_frustum_offset"; + + public const string GetNear = "get_near"; + public const string SetNear = "set_near"; + + public const string GetFar = "get_far"; + public const string SetFar = "set_far"; + } +} diff --git a/addons/phantom_camera/scripts/resources/Camera3DResource.cs.uid b/addons/phantom_camera/scripts/resources/Camera3DResource.cs.uid new file mode 100644 index 0000000..d66b43e --- /dev/null +++ b/addons/phantom_camera/scripts/resources/Camera3DResource.cs.uid @@ -0,0 +1 @@ +uid://jedyxlihuwbj diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs new file mode 100644 index 0000000..16b7273 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs @@ -0,0 +1,92 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoise2D(Resource resource) +{ + public readonly Resource Resource = resource; + + public float Amplitude + { + get => (float)Resource.Call(MethodName.GetAmplitude); + set => Resource.Call(MethodName.SetAmplitude, value); + } + + public float Frequency + { + get => (float)Resource.Call(MethodName.GetFrequency); + set => Resource.Call(MethodName.SetFrequency, value); + } + + public bool RandomizeNoiseSeed + { + get => (bool)Resource.Call(MethodName.GetRandomizeNoiseSeed); + set => Resource.Call(MethodName.SetRandomizeNoiseSeed, value); + } + + public int NoiseSeed + { + get => (int)Resource.Call(MethodName.GetNoiseSeed); + set => Resource.Call(MethodName.SetNoiseSeed, value); + } + + public bool RotationalNoise + { + get => (bool)Resource.Call(MethodName.GetRotationalNoise); + set => Resource.Call(MethodName.SetRotationalNoise, value); + } + + public bool PositionalNoise + { + get => (bool)Resource.Call(MethodName.GetPositionalNoise); + set => Resource.Call(MethodName.SetPositionalNoise, value); + } + + public float RotationalMultiplier + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplier); + set => Resource.Call(MethodName.SetRotationalMultiplier, value); + } + + public float PositionalMultiplierX + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierX); + set => Resource.Call(MethodName.SetPositionalMultiplierX, value); + } + + public float PositionalMultiplierY + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierY); + set => Resource.Call(MethodName.SetPositionalMultiplierY, value); + } + + public static class MethodName + { + public const string GetAmplitude = "get_amplitude"; + public const string SetAmplitude = "set_amplitude"; + + public const string GetFrequency = "get_frequency"; + public const string SetFrequency = "set_frequency"; + + public const string GetRandomizeNoiseSeed = "get_randomize_noise_seed"; + public const string SetRandomizeNoiseSeed = "set_randomize_noise_seed"; + + public const string GetNoiseSeed = "get_noise_seed"; + public const string SetNoiseSeed = "set_noise_seed"; + + public const string GetRotationalNoise = "get_rotational_noise"; + public const string SetRotationalNoise = "set_rotational_noise"; + + public const string GetPositionalNoise = "get_positional_noise"; + public const string SetPositionalNoise = "set_positional_noise"; + + public const string GetRotationalMultiplier = "get_rotational_multiplier"; + public const string SetRotationalMultiplier = "set_rotational_multiplier"; + + public const string GetPositionalMultiplierX = "get_positional_multiplier_x"; + public const string SetPositionalMultiplierX = "set_positional_multiplier_x"; + + public const string GetPositionalMultiplierY = "get_positional_multiplier_y"; + public const string SetPositionalMultiplierY = "set_positional_multiplier_y"; + } +} diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs.uid b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs.uid new file mode 100644 index 0000000..16ddb84 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs.uid @@ -0,0 +1 @@ +uid://capjdoxs6gs6r diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs new file mode 100644 index 0000000..175a427 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs @@ -0,0 +1,119 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoise3D(Resource resource) +{ + public readonly Resource Resource = resource; + + public float Amplitude + { + get => (float)Resource.Call(MethodName.GetAmplitude); + set => Resource.Call(MethodName.SetAmplitude, value); + } + + public float Frequency + { + get => (float)Resource.Call(MethodName.GetFrequency); + set => Resource.Call(MethodName.SetFrequency, value); + } + + public bool RandomizeNoiseSeed + { + get => (bool)Resource.Call(MethodName.GetRandomizeNoiseSeed); + set => Resource.Call(MethodName.SetRandomizeNoiseSeed, value); + } + + public int NoiseSeed + { + get => (int)Resource.Call(MethodName.GetNoiseSeed); + set => Resource.Call(MethodName.SetNoiseSeed, value); + } + + public bool RotationalNoise + { + get => (bool)Resource.Call(MethodName.GetRotationalNoise); + set => Resource.Call(MethodName.SetRotationalNoise, value); + } + + public bool PositionalNoise + { + get => (bool)Resource.Call(MethodName.GetPositionalNoise); + set => Resource.Call(MethodName.SetPositionalNoise, value); + } + + public float RotationalMultiplierX + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplierX); + set => Resource.Call(MethodName.SetRotationalMultiplierX, value); + } + + public float RotationalMultiplierY + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplierY); + set => Resource.Call(MethodName.SetRotationalMultiplierY, value); + } + + public float RotationalMultiplierZ + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplierZ); + set => Resource.Call(MethodName.SetRotationalMultiplierZ, value); + } + + public float PositionalMultiplierX + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierX); + set => Resource.Call(MethodName.SetPositionalMultiplierX, value); + } + + public float PositionalMultiplierY + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierY); + set => Resource.Call(MethodName.SetPositionalMultiplierY, value); + } + + public float PositionalMultiplierZ + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierZ); + set => Resource.Call(MethodName.SetPositionalMultiplierZ, value); + } + + public static class MethodName + { + public const string GetAmplitude = "get_amplitude"; + public const string SetAmplitude = "set_amplitude"; + + public const string GetFrequency = "get_frequency"; + public const string SetFrequency = "set_frequency"; + + public const string GetRandomizeNoiseSeed = "get_randomize_noise_seed"; + public const string SetRandomizeNoiseSeed = "set_randomize_noise_seed"; + + public const string GetNoiseSeed = "get_noise_seed"; + public const string SetNoiseSeed = "set_noise_seed"; + + public const string GetRotationalNoise = "get_rotational_noise"; + public const string SetRotationalNoise = "set_rotational_noise"; + + public const string GetPositionalNoise = "get_positional_noise"; + public const string SetPositionalNoise = "set_positional_noise"; + + public const string GetRotationalMultiplierX = "get_rotational_multiplier_x"; + public const string SetRotationalMultiplierX = "set_rotational_multiplier_x"; + + public const string GetRotationalMultiplierY = "get_rotational_multiplier_y"; + public const string SetRotationalMultiplierY = "set_rotational_multiplier_y"; + + public const string GetRotationalMultiplierZ = "get_rotational_multiplier_z"; + public const string SetRotationalMultiplierZ = "set_rotational_multiplier_z"; + + public const string GetPositionalMultiplierX = "get_positional_multiplier_x"; + public const string SetPositionalMultiplierX = "set_positional_multiplier_x"; + + public const string GetPositionalMultiplierY = "get_positional_multiplier_y"; + public const string SetPositionalMultiplierY = "set_positional_multiplier_y"; + + public const string GetPositionalMultiplierZ = "get_positional_multiplier_z"; + public const string SetPositionalMultiplierZ = "set_positional_multiplier_z"; + } +} diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs.uid b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs.uid new file mode 100644 index 0000000..53d184f --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs.uid @@ -0,0 +1 @@ +uid://chk7643ynhe4f diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs new file mode 100644 index 0000000..1c332b7 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs @@ -0,0 +1,64 @@ +using Godot; + +namespace PhantomCamera; + +public enum TransitionType +{ + Linear, + Sine, + Quint, + Quart, + Quad, + Expo, + Elastic, + Cubic, + Circ, + Bounce, + Back +} + +public enum EaseType +{ + EaseIn, + EaseOut, + EaseInOut, + EaseOutIn +} + +public static class PhantomCameraTweenExtensions +{ + public static PhantomCameraTween AsPhantomCameraTween(this Resource resource) + { + return new PhantomCameraTween(resource); + } +} + +public class PhantomCameraTween(Resource tweenResource) +{ + public Resource Resource { get; } = tweenResource; + + public float Duration + { + get => (float)Resource.Get(PropertyName.Duration); + set => Resource.Set(PropertyName.Duration, value); + } + + public TransitionType Transition + { + get => (TransitionType)(int)Resource.Get(PropertyName.Transition); + set => Resource.Set(PropertyName.Transition, (int)value); + } + + public EaseType Ease + { + get => (EaseType)(int)Resource.Get(PropertyName.Ease); + set => Resource.Set(PropertyName.Ease, (int)value); + } + + public static class PropertyName + { + public const string Duration = "duration"; + public const string Transition = "transition"; + public const string Ease = "ease"; + } +} diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs.uid b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs.uid new file mode 100644 index 0000000..dd50ead --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs.uid @@ -0,0 +1 @@ +uid://ybr5c2s0tfvx diff --git a/addons/phantom_camera/themes/button_focus.tres b/addons/phantom_camera/themes/button_focus.tres new file mode 100644 index 0000000..e6fcc45 --- /dev/null +++ b/addons/phantom_camera/themes/button_focus.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://p058hmj3uut0"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/addons/phantom_camera/themes/button_hover.tres b/addons/phantom_camera/themes/button_hover.tres new file mode 100644 index 0000000..9d37a86 --- /dev/null +++ b/addons/phantom_camera/themes/button_hover.tres @@ -0,0 +1,13 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://5weqvkjsfso3"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/addons/phantom_camera/themes/button_normal.tres b/addons/phantom_camera/themes/button_normal.tres new file mode 100644 index 0000000..4eae33d --- /dev/null +++ b/addons/phantom_camera/themes/button_normal.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bclbwo3xrdat0"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/addons/phantom_camera/themes/theme.tres b/addons/phantom_camera/themes/theme.tres new file mode 100644 index 0000000..7ce53d8 --- /dev/null +++ b/addons/phantom_camera/themes/theme.tres @@ -0,0 +1,102 @@ +[gd_resource type="Theme" load_steps=12 format=3 uid="uid://bhppejri5dbsf"] + +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="1_5rtjh"] +[ext_resource type="StyleBox" uid="uid://5weqvkjsfso3" path="res://addons/phantom_camera/themes/button_hover.tres" id="2_du6h5"] +[ext_resource type="StyleBox" uid="uid://bclbwo3xrdat0" path="res://addons/phantom_camera/themes/button_normal.tres" id="3_a8j1f"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ek0y3"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rjkuq"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_x7u0w"] +content_margin_top = 2.0 +content_margin_right = 8.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dln2q"] +content_margin_top = 8.0 +content_margin_bottom = 8.0 +draw_center = false + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wk7ot"] +bg_color = Color(0.227451, 0.72549, 0.603922, 1) +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jidrt"] +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2xwc"] +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ul127"] +draw_center = false +border_width_left = 4 +border_width_right = 4 +border_color = Color(0.8, 0.8, 0.8, 0) + +[resource] +default_font = ExtResource("1_5rtjh") +Button/colors/font_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/font_focus_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/font_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/font_hover_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/font_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_focus_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_hover_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/icon_normal_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/styles/focus = SubResource("StyleBoxFlat_ek0y3") +Button/styles/hover = ExtResource("2_du6h5") +Button/styles/hover_pressed = null +Button/styles/normal = ExtResource("3_a8j1f") +Button/styles/pressed = SubResource("StyleBoxFlat_rjkuq") +PanelContainer/styles/panel = SubResource("StyleBoxFlat_x7u0w") +ScrollContainer/styles/panel = SubResource("StyleBoxFlat_dln2q") +VBoxContainer/constants/separation = 8 +VScrollBar/styles/grabber = SubResource("StyleBoxFlat_wk7ot") +VScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_jidrt") +VScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_o2xwc") +VScrollBar/styles/scroll = SubResource("StyleBoxFlat_ul127") diff --git a/objects/entities/brick_player.tscn b/objects/entities/brick_player.tscn index 956fe7c..57cafb0 100644 --- a/objects/entities/brick_player.tscn +++ b/objects/entities/brick_player.tscn @@ -82,7 +82,8 @@ collision_layer = 4 collision_mask = 43 script = ExtResource("1_yysbb") MovementTypes = Dictionary[String, NodePath]({ -"platform": NodePath("Movements/PlatformMovement") +"platform": NodePath("Movements/PlatformMovement"), +"ship": NodePath("Movements/ShipMovement") }) ShipSprite = NodePath("Graphics/Ship") @@ -271,6 +272,7 @@ ScreenNotifier = NodePath("../VisibleOnScreenNotifier2D") HealthComponent = NodePath("../HealthComponent") [node name="ProgressiveDamageComponent" type="Node" parent="." node_paths=PackedStringArray("HealthComponent", "Sprite", "PlatformMovement")] +process_mode = 4 script = ExtResource("38_dhjci") HealthComponent = NodePath("../HealthComponent") Sprite = NodePath("../Graphics/Root/Base") diff --git a/objects/entities/green_laser.tscn b/objects/entities/green_laser.tscn index ed02b47..6536713 100644 --- a/objects/entities/green_laser.tscn +++ b/objects/entities/green_laser.tscn @@ -22,13 +22,14 @@ Area = NodePath("..") metadata/_custom_type_script = "uid://dkmxhjtmu5xlb" [node name="CollisionShape2D" type="CollisionShape2D" parent="."] +visible = false position = Vector2(8, -0.5) shape = SubResource("RectangleShape2D_n4uav") [node name="Line2D" type="Line2D" parent="."] points = PackedVector2Array(0, 0, 16, 0) width = 2.0 -default_color = Color(0, 94.012, 1, 1) +default_color = Color(0, 90, 0, 1) [node name="BulletComponent" type="Node" parent="." node_paths=PackedStringArray("Area")] script = ExtResource("2_2bmqm") diff --git a/objects/entities/spaceship_enter.tscn b/objects/entities/spaceship_enter.tscn index 6d70cb0..ac6cd83 100644 --- a/objects/entities/spaceship_enter.tscn +++ b/objects/entities/spaceship_enter.tscn @@ -9,13 +9,10 @@ radius = 16.1245 [node name="Spaceship Enter" type="Area2D"] collision_layer = 0 collision_mask = 4 +script = ExtResource("2_wanmd") [node name="Sprite2D" type="Sprite2D" parent="."] texture = ExtResource("1_r82pf") [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("CircleShape2D_wanmd") - -[node name="SpaceshipEnterComponent" type="Node" parent="." node_paths=PackedStringArray("Area")] -script = ExtResource("2_wanmd") -Area = NodePath("..") diff --git a/objects/level/base_level.tscn b/objects/level/base_level.tscn index 1329c6c..067a68c 100644 --- a/objects/level/base_level.tscn +++ b/objects/level/base_level.tscn @@ -70,7 +70,8 @@ limit_top = -10000000 limit_right = 10000000 limit_bottom = 10000000 -[node name="PhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_target")] +[node name="PhantomCamera" type="Node2D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true top_level = true script = ExtResource("6_6imqp") follow_mode = 2 diff --git a/project.godot b/project.godot index 58c0616..ef34705 100644 --- a/project.godot +++ b/project.godot @@ -16,7 +16,7 @@ config/name_localized={ "pl": "Przygody Pana Cegły" } config/version="in-dev" -run/main_scene="uid://cl00e2ocomk3m" +run/main_scene="uid://bhad760x3vvco" config/use_custom_user_dir=true config/custom_user_dir_name="MrBrickAdventures" config/features=PackedStringArray("4.4", "C#", "GL Compatibility") @@ -38,6 +38,7 @@ AchievementsManager="*res://objects/achievements.tscn" UIManager="*res://Autoloads/UIManager.cs" ConfigFileHandler="*res://Autoloads/ConfigFileHandler.cs" SaveSystem="*res://Autoloads/SaveSystem.cs" +Console="*res://addons/console/console.gd" [debug] diff --git a/scenes/level_village_1.tscn b/scenes/level_village_1.tscn index e2ae812..1790e7a 100644 --- a/scenes/level_village_1.tscn +++ b/scenes/level_village_1.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=23 format=4 uid="uid://bol7g83v2accs"] +[gd_scene load_steps=22 format=4 uid="uid://bol7g83v2accs"] [ext_resource type="PackedScene" uid="uid://bqi5s710xb1ju" path="res://objects/entities/brick_player.tscn" id="1_dnj2y"] [ext_resource type="PackedScene" uid="uid://cawlpch2lk3a2" path="res://objects/level/world_environment.tscn" id="2_1vw1j"] @@ -12,7 +12,6 @@ [ext_resource type="TileSet" uid="uid://cu2sx7qigrqnv" path="res://resources/tilesets/village/terain.tres" id="9_ttvjm"] [ext_resource type="TileSet" uid="uid://bc5a20s6kuy8e" path="res://resources/tilesets/village/entities.tres" id="10_ei558"] [ext_resource type="TileSet" uid="uid://bbppo0irxdmqy" path="res://resources/tilesets/village/foreground.tres" id="11_w7c5i"] -[ext_resource type="PackedScene" uid="uid://bqom4cm7r18db" path="res://objects/entities/killzone.tscn" id="13_tvdre"] [ext_resource type="PackedScene" uid="uid://d0s2abysa86rq" path="res://objects/entities/child.tscn" id="15_vqevu"] [ext_resource type="PackedScene" uid="uid://12jnkdygpxwc" path="res://objects/entities/exit_level.tscn" id="16_chnw1"] [ext_resource type="PackedScene" uid="uid://b4pdt1gv2ymyi" path="res://objects/tooltip.tscn" id="18_4bhfj"] @@ -116,10 +115,6 @@ tile_set = ExtResource("10_ei558") [node name="Foreground layer" type="TileMapLayer" parent="."] tile_set = ExtResource("11_w7c5i") -[node name="Killzone" parent="." instance=ExtResource("13_tvdre")] -process_mode = 4 -position = Vector2(215, 324) - [node name="Child" parent="." instance=ExtResource("15_vqevu")] position = Vector2(-162, -256) diff --git a/scenes/level_village_2.tscn b/scenes/level_village_2.tscn index a567269..77d1fd3 100644 --- a/scenes/level_village_2.tscn +++ b/scenes/level_village_2.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=25 format=4 uid="uid://chqb11pfoqmeb"] +[gd_scene load_steps=24 format=4 uid="uid://chqb11pfoqmeb"] [ext_resource type="PackedScene" uid="uid://bqi5s710xb1ju" path="res://objects/entities/brick_player.tscn" id="1_wcma7"] [ext_resource type="PackedScene" uid="uid://cawlpch2lk3a2" path="res://objects/level/world_environment.tscn" id="2_ot3dy"] @@ -12,7 +12,6 @@ [ext_resource type="TileSet" uid="uid://bc5a20s6kuy8e" path="res://resources/tilesets/village/entities.tres" id="10_4r26m"] [ext_resource type="TileSet" uid="uid://bbppo0irxdmqy" path="res://resources/tilesets/village/foreground.tres" id="11_r0ngp"] [ext_resource type="TileSet" uid="uid://ccffmjebvuoaj" path="res://resources/tilesets/village/small_foreground.tres" id="13_lc0ll"] -[ext_resource type="PackedScene" uid="uid://bqom4cm7r18db" path="res://objects/entities/killzone.tscn" id="13_sw2hn"] [ext_resource type="PackedScene" uid="uid://12jnkdygpxwc" path="res://objects/entities/exit_level.tscn" id="15_hcsb6"] [ext_resource type="PackedScene" uid="uid://d0s2abysa86rq" path="res://objects/entities/child.tscn" id="16_lc0ll"] [ext_resource type="PackedScene" uid="uid://to2xnqev0pu1" path="res://objects/entities/cage.tscn" id="17_h4uvs"] @@ -67,6 +66,12 @@ process_material = SubResource("ParticleProcessMaterial_lgb3u") [node name="UI Layer" parent="." instance=ExtResource("3_cjqhe")] +[node name="HUD" parent="UI Layer" index="0" node_paths=PackedStringArray("Health")] +Health = NodePath("../../Brick Player/HealthComponent") + +[node name="Marketplace" parent="UI Layer" index="3" node_paths=PackedStringArray("SkillUnlockedComponent")] +SkillUnlockedComponent = NodePath("../../Brick Player/SkillUnlockerComponent") + [node name="Global Light" parent="." instance=ExtResource("4_wykfl")] [node name="Camera2D" parent="." instance=ExtResource("5_8nvkd")] @@ -111,9 +116,6 @@ tile_set = ExtResource("11_r0ngp") tile_map_data = PackedByteArray("AABw/ykAAAABAAAAAABr/ykAAAAAAAAAAABn/ykAAAACAAAAAABl/ykAAAABAAAAAABj/ykAAAACAAAAAABh/ykAAAABAAAAAABa/ykAAAABAAAAAABY/ykAAAACAAAAAABU/ykAAAADAAAAAABP/ykAAAAAAAAAAACD/ykAAAABAAAAAACO/ykAAAACAAAAAACT/ykAAAABAAAAAACV/ykAAAAAAAAAAACa/ykAAAADAAAAAACq/ykAAAACAAAAAACr/ykAAAAAAAAAAADi/wMAAAAAAAAAAADk/wMAAAACAAAAAADp/wMAAAABAAAAAADs/wMAAAAAAAAAAADt/wMAAAABAAAAAADx/wMAAAADAAAAAADy/wMAAAAAAAAAAADz/wMAAAACAAAAAAD0/wMAAAADAAAAAAD5/wMAAAAAAAAAAAD6/wMAAAAAAAAAAAD7/wMAAAABAAAAAAACAAMAAAABAAAAAAAJAAMAAAABAAAAAAANAAMAAAAAAAAAAAAUAAMAAAABAAAAAAAYAAMAAAADAAAAAAAaAAMAAAADAAAAAAAcAAMAAAACAAAAAAAgAAMAAAAAAAAAAAAiAAMAAAACAAAAAAAmAAMAAAADAAAAAAAoAAMAAAAAAAAAAABGAAMAAAADAAAAAABEAAMAAAACAAAAAABCAAMAAAABAAAAAAA8AAMAAAACAAAAAAA3AAMAAAACAAAAAAA0AAMAAAADAAAAAAAxAAMAAAADAAAAAAAwAAMAAAACAAAAAAAfAAMAAAAAAAAAAAATAAMAAAAAAAAAAAASAAMAAAABAAAAAAAOAAMAAAAAAAAAAABWAAUAAAABAAAAAABZAAUAAAADAAAAAABaAAUAAAABAAAAAABkAAUAAAACAAAAAAB1AAUAAAADAAAAAAB2AAUAAAABAAAAAAB/AAUAAAADAAAAAACsAO//AAAAAAAAAACrAO//AAACAAAAAACnAO//AAACAAAAAACgAO//AAABAAAAAACVAO//AAACAAAAAACUAO//AAADAAAAAACTAO//AAACAAAAAACNAO//AAAAAAAAAACxANX/AAABAAAAAACzANX/AAACAAAAAAC7ANX/AAACAAAAAADBANX/AAACAAAAAADDANX/AAABAAAAAADMANX/AAABAAAAAADQANX/AAABAAAAAADXANX/AAABAAAAAADZANX/AAABAAAAAADdANX/AAAAAAAAAADfANX/AAACAAAAAADnANX/AAABAAAAAADoANX/AAACAAAAAACiAJ//AAACAAAAAACcAJ//AAADAAAAAACbAJ//AAAAAAAAAACYAJ//AAADAAAAAACSAJ//AAADAAAAAACJAJ//AAADAAAAAACGAJ//AAABAAAAAACEAJ//AAACAAAAAACAAJ//AAABAAAAAAB/AJ//AAADAAAAAAB9AJ//AAACAAAAAAA=") tile_set = ExtResource("13_lc0ll") -[node name="Killzone" parent="." instance=ExtResource("13_sw2hn")] -position = Vector2(170, 582) - [node name="ExitLevel" parent="." instance=ExtResource("15_hcsb6")] position = Vector2(987, -776) @@ -155,5 +157,8 @@ position = Vector2(792, -784) [node name="Lever" parent="." instance=ExtResource("20_h4uvs")] position = Vector2(-231, -776) +[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/DeathScreen" method="OnPlayerDeath"] +[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/GameOverScreen" method="OnPlayerDeath"] + [editable path="Brick Player"] [editable path="UI Layer"] diff --git a/scenes/level_village_3.tscn b/scenes/level_village_3.tscn index 91ddaed..78b35dc 100644 --- a/scenes/level_village_3.tscn +++ b/scenes/level_village_3.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=31 format=4 uid="uid://h60obxmju6mo"] +[gd_scene load_steps=30 format=4 uid="uid://h60obxmju6mo"] [ext_resource type="PackedScene" uid="uid://dyp4i4ru2j2jh" path="res://objects/fxs/explosion_fx.tscn" id="1_p30ax"] [ext_resource type="PackedScene" uid="uid://dx80ivlvuuew4" path="res://objects/fxs/fire_fx.tscn" id="2_a7yjf"] @@ -16,7 +16,6 @@ [ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="14_k7w2w"] [ext_resource type="PackedScene" uid="uid://d0s2abysa86rq" path="res://objects/entities/child.tscn" id="15_dv6gh"] [ext_resource type="PackedScene" uid="uid://6foggu31cu14" path="res://objects/level/ui_layer.tscn" id="16_nr2eo"] -[ext_resource type="PackedScene" uid="uid://bqom4cm7r18db" path="res://objects/entities/killzone.tscn" id="17_3xroh"] [ext_resource type="PackedScene" uid="uid://b4pdt1gv2ymyi" path="res://objects/tooltip.tscn" id="18_l3a7y"] [ext_resource type="PackedScene" uid="uid://cawlpch2lk3a2" path="res://objects/level/world_environment.tscn" id="20_embdf"] [ext_resource type="PackedScene" uid="uid://cywsu7yrtjdog" path="res://objects/level/global_light.tscn" id="21_fytod"] @@ -323,8 +322,11 @@ position = Vector2(880, -578) [node name="UI Layer" parent="." instance=ExtResource("16_nr2eo")] -[node name="Killzone" parent="." instance=ExtResource("17_3xroh")] -position = Vector2(2600, 802) +[node name="HUD" parent="UI Layer" index="0" node_paths=PackedStringArray("Health")] +Health = NodePath("../../Brick Player/HealthComponent") + +[node name="Marketplace" parent="UI Layer" index="3" node_paths=PackedStringArray("SkillUnlockedComponent")] +SkillUnlockedComponent = NodePath("../../Brick Player/SkillUnlockerComponent") [node name="Tooltip" parent="." instance=ExtResource("18_l3a7y")] position = Vector2(1016, -104) @@ -345,6 +347,8 @@ position = Vector2(1244, -41) [node name="SmallHealPotion3" parent="." instance=ExtResource("23_m6h4x")] position = Vector2(1359, -42) +[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/DeathScreen" method="OnPlayerDeath"] +[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/GameOverScreen" method="OnPlayerDeath"] + [editable path="Brick Player"] [editable path="UI Layer"] -[editable path="Killzone"] diff --git a/scenes/level_village_4.tscn b/scenes/level_village_4.tscn index 5e9c596..5a4b604 100644 --- a/scenes/level_village_4.tscn +++ b/scenes/level_village_4.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=35 format=4 uid="uid://bhad760x3vvco"] +[gd_scene load_steps=34 format=4 uid="uid://bhad760x3vvco"] [ext_resource type="PackedScene" uid="uid://bqi5s710xb1ju" path="res://objects/entities/brick_player.tscn" id="1_k3uyd"] [ext_resource type="PackedScene" uid="uid://bon6raeddf3tu" path="res://objects/entities/chaser.tscn" id="1_xraal"] @@ -13,7 +13,6 @@ [ext_resource type="TileSet" uid="uid://cu2sx7qigrqnv" path="res://resources/tilesets/village/terain.tres" id="9_bjo44"] [ext_resource type="TileSet" uid="uid://bc5a20s6kuy8e" path="res://resources/tilesets/village/entities.tres" id="10_gg8rp"] [ext_resource type="TileSet" uid="uid://bbppo0irxdmqy" path="res://resources/tilesets/village/foreground.tres" id="11_23awj"] -[ext_resource type="PackedScene" uid="uid://bqom4cm7r18db" path="res://objects/entities/killzone.tscn" id="13_1heob"] [ext_resource type="PackedScene" uid="uid://lpovacvt3yyj" path="res://objects/entities/spaceship_enter.tscn" id="14_bajwe"] [ext_resource type="PackedScene" uid="uid://d0s2abysa86rq" path="res://objects/entities/child.tscn" id="15_3iocp"] [ext_resource type="PackedScene" uid="uid://xp4njljog0x2" path="res://objects/entities/flying_enemy.tscn" id="18_162yw"] @@ -113,10 +112,19 @@ texture = SubResource("CanvasTexture_o1yb3") [node name="Chaser" parent="." instance=ExtResource("1_xraal")] position = Vector2(578.405, 15.8615) +[node name="ChaseLevelComponent" parent="Chaser" index="0" node_paths=PackedStringArray("ChaseTarget")] +ChaseTarget = NodePath("../../Chase Target") + [node name="WorldEnvironment" parent="." instance=ExtResource("2_a7hm7")] [node name="UI Layer" parent="." instance=ExtResource("3_p8wo6")] +[node name="HUD" parent="UI Layer" index="0" node_paths=PackedStringArray("Health")] +Health = NodePath("../../Brick Player/HealthComponent") + +[node name="Marketplace" parent="UI Layer" index="3" node_paths=PackedStringArray("SkillUnlockedComponent")] +SkillUnlockedComponent = NodePath("../../Brick Player/SkillUnlockerComponent") + [node name="Global Light" parent="." instance=ExtResource("4_0lkg8")] [node name="Lever" parent="." instance=ExtResource("7_1bwe8")] @@ -130,7 +138,8 @@ limit_top = -10000000 limit_right = 10000000 limit_bottom = 10000000 -[node name="PhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_target")] +[node name="PhantomCamera" type="Node2D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true top_level = true script = ExtResource("6_i5rlu") follow_mode = 2 @@ -156,9 +165,6 @@ tile_set = ExtResource("10_gg8rp") [node name="Foreground layer" type="TileMapLayer" parent="."] tile_set = ExtResource("11_23awj") -[node name="Killzone" parent="." instance=ExtResource("13_1heob")] -position = Vector2(215, 324) - [node name="Spaceship Enter" parent="." instance=ExtResource("14_bajwe")] position = Vector2(559, 15) @@ -256,6 +262,15 @@ position = Vector2(7148, 22) [node name="CollisionShape2D" parent="Spaceship exit" index="0"] position = Vector2(16.5, -10) +[connection signal="SpaceshipEntered" from="Spaceship Enter" to="Chaser/ChaseLevelComponent" method="OnShipEntered"] +[connection signal="SpaceshipEntered" from="Spaceship Enter" to="Brick Player" method="OnSpaceshipEntered"] +[connection signal="SpaceshipEntered" from="Spaceship Enter" to="Brick Player/ShipShooter" method="OnShipEntered"] +[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/DeathScreen" method="OnPlayerDeath"] +[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/GameOverScreen" method="OnPlayerDeath"] +[connection signal="SpaceshipExit" from="Spaceship exit" to="Chaser/ChaseLevelComponent" method="OnShipExited"] +[connection signal="SpaceshipExit" from="Spaceship exit" to="Brick Player" method="OnSpaceshipExited"] +[connection signal="SpaceshipExit" from="Spaceship exit" to="Brick Player/ShipShooter" method="OnShipExited"] + [editable path="Chaser"] [editable path="UI Layer"] [editable path="Spaceship Enter"] diff --git a/scripts/SkillManager.cs b/scripts/SkillManager.cs index ad53727..d2bf4a9 100644 --- a/scripts/SkillManager.cs +++ b/scripts/SkillManager.cs @@ -97,7 +97,6 @@ public partial class SkillManager : Node { if (_gameManager.IsSkillUnlocked(sd)) { - GD.Print("Applying skill: ", sd.Name); CallDeferred(MethodName.AddSkill, sd); } else diff --git a/scripts/UI/Marketplace.cs b/scripts/UI/Marketplace.cs index 4d33335..86b094a 100644 --- a/scripts/UI/Marketplace.cs +++ b/scripts/UI/Marketplace.cs @@ -45,18 +45,16 @@ public partial class Marketplace : Control public override void _Input(InputEvent @event) { - var root = Owner as Control; - if (!@event.IsActionPressed("show_marketplace")) return; - if (root != null && root.IsVisible()) + if (IsVisible()) { - root.Hide(); + Hide(); foreach (var c in ComponentsToDisable) c.ProcessMode = ProcessModeEnum.Inherit; } else { - root?.Show(); + Show(); foreach (var c in ComponentsToDisable) c.ProcessMode = ProcessModeEnum.Disabled; } } diff --git a/scripts/components/ChaseLevelComponent.cs b/scripts/components/ChaseLevelComponent.cs index d22a499..1595155 100644 --- a/scripts/components/ChaseLevelComponent.cs +++ b/scripts/components/ChaseLevelComponent.cs @@ -1,4 +1,5 @@ using Godot; +using PhantomCamera; namespace Mr.BrickAdventures.scripts.components; @@ -6,7 +7,6 @@ public partial class ChaseLevelComponent : Node { [Export] public float ChaseSpeed { get; set; } = 200.0f; [Export] public Marker2D ChaseTarget { get; set; } - [Export] public GodotObject PhantomCamera { get; set; } [Export] public float MinimumDistance { get; set; } = 10f; [Signal] @@ -17,8 +17,17 @@ public partial class ChaseLevelComponent : Node private bool _isChasing = false; private Node2D _previousCameraFollowTarget = null; + private PhantomCamera2D _phantomCamera = null; + private Node2D _root = null; + - public override void _Process(double delta) + public override void _Ready() + { + _phantomCamera = GetNode("../../%PhantomCamera").AsPhantomCamera2D(); + _root = Owner as Node2D; + } + + public override void _PhysicsProcess(double delta) { if (!_isChasing) return; if (ChaseTarget == null) return; @@ -31,21 +40,22 @@ public partial class ChaseLevelComponent : Node var targetPosition = ChaseTarget.GlobalPosition; - if (Owner is not Node2D root) return; + if (_root == null) return; - var direction = (targetPosition - root.GlobalPosition).Normalized(); - root.GlobalPosition += direction * ChaseSpeed * (float)delta; + var direction = (targetPosition - _root.GlobalPosition).Normalized(); + var speed = direction * ChaseSpeed * (float)delta; + _root.GlobalPosition += speed; } public void OnShipEntered() { - if (ChaseTarget == null || PhantomCamera == null) + if (ChaseTarget == null || _phantomCamera == null) return; if (_isChasing) return; - _previousCameraFollowTarget = (Node2D)PhantomCamera.Call("get_follow_target"); - PhantomCamera.Call("set_follow_target", Owner as Node2D); + _previousCameraFollowTarget = _phantomCamera.FollowTarget; + _phantomCamera.FollowTarget = _root; EmitSignalChaseStarted(); _isChasing = true; } @@ -70,9 +80,9 @@ public partial class ChaseLevelComponent : Node private void StopChasing() { - if (PhantomCamera == null) return; + if (_phantomCamera == null) return; - PhantomCamera.Call("set_follow_target", _previousCameraFollowTarget); + _phantomCamera.FollowTarget = _previousCameraFollowTarget; EmitSignalChaseStopped(); _isChasing = false; } diff --git a/scripts/components/EnemyDeathComponent.cs b/scripts/components/EnemyDeathComponent.cs index 491af69..3a04c22 100644 --- a/scripts/components/EnemyDeathComponent.cs +++ b/scripts/components/EnemyDeathComponent.cs @@ -28,7 +28,7 @@ public partial class EnemyDeathComponent : Node private void OnDeath() { - CallDeferred(nameof(Die)); + _ = Die(); } private async Task Die() diff --git a/scripts/components/FlashingComponent.cs b/scripts/components/FlashingComponent.cs index 7a7db70..e808ea6 100644 --- a/scripts/components/FlashingComponent.cs +++ b/scripts/components/FlashingComponent.cs @@ -30,11 +30,10 @@ public partial class FlashingComponent : Node public void StartFlashing() { if (Sprite == null) return; - - _tween?.Kill(); - + if (_tween != null && _tween.IsRunning()) return; + _tween = CreateTween(); - _tween.SetParallel(true); + _tween.SetParallel(false); var flashes = (int)(FlashDuration / FlashTime); for (var i = 0; i < flashes; i++) diff --git a/scripts/components/PlatformMovementComponent.cs b/scripts/components/PlatformMovementComponent.cs index 8f4f7c6..03028fa 100644 --- a/scripts/components/PlatformMovementComponent.cs +++ b/scripts/components/PlatformMovementComponent.cs @@ -123,7 +123,8 @@ public partial class PlatformMovementComponent : Node2D, IMovement Body.Velocity = new Vector2(direction * Speed, Body.Velocity.Y); else Body.Velocity = new Vector2(Mathf.MoveToward(Body.Velocity.X, 0, Speed), Body.Velocity.Y); - + + PreviousVelocity = Body.Velocity; Body.MoveAndSlide(); } diff --git a/scripts/components/PlayerDeathComponent.cs b/scripts/components/PlayerDeathComponent.cs index 1f39128..7db4780 100644 --- a/scripts/components/PlayerDeathComponent.cs +++ b/scripts/components/PlayerDeathComponent.cs @@ -31,7 +31,6 @@ public partial class PlayerDeathComponent : Node2D } _gameManager.RemoveLives(1); - GD.Print("Player death, lives left: " + _gameManager.GetLives()); _gameManager.ResetCurrentSessionState(); } } \ No newline at end of file diff --git a/scripts/components/ShipShooterComponent.cs b/scripts/components/ShipShooterComponent.cs index cb6d4d9..1ae46f1 100644 --- a/scripts/components/ShipShooterComponent.cs +++ b/scripts/components/ShipShooterComponent.cs @@ -10,7 +10,7 @@ public partial class ShipShooterComponent : Node [Export] public Marker2D BulletSpawn { get; set; } [Export] public AudioStreamPlayer2D ShootSfx { get; set; } - private bool _canShoot = false; + private bool _canShoot = true; public override void _Ready() { diff --git a/scripts/components/SpaceshipEnterComponent.cs b/scripts/components/SpaceshipEnterComponent.cs index 6eb0355..16b246e 100644 --- a/scripts/components/SpaceshipEnterComponent.cs +++ b/scripts/components/SpaceshipEnterComponent.cs @@ -2,20 +2,19 @@ using Godot; namespace Mr.BrickAdventures.scripts.components; -public partial class SpaceshipEnterComponent : Node +public partial class SpaceshipEnterComponent : Area2D { - [Export] public Area2D Area { get; set; } [Signal] public delegate void SpaceshipEnteredEventHandler(); public override void _Ready() { - Area.BodyEntered += OnBodyEntered; + BodyEntered += OnBodyEntered; } private void OnBodyEntered(Node2D body) { if (body is not PlayerController) return; EmitSignalSpaceshipEntered(); - Owner.QueueFree(); + QueueFree(); } } \ No newline at end of file diff --git a/scripts/components/SpaceshipExitComponent.cs b/scripts/components/SpaceshipExitComponent.cs index 4cf413f..6d75270 100644 --- a/scripts/components/SpaceshipExitComponent.cs +++ b/scripts/components/SpaceshipExitComponent.cs @@ -2,14 +2,13 @@ using Godot; namespace Mr.BrickAdventures.scripts.components; -public partial class SpaceshipExitComponent : Node +public partial class SpaceshipExitComponent : Area2D { - [Export] public Area2D Area { get; set; } [Signal] public delegate void SpaceshipExitEventHandler(); public override void _Ready() { - Area.BodyEntered += OnBodyEntered; + BodyEntered += OnBodyEntered; } private void OnBodyEntered(Node2D body)