diff --git a/addons/anthonyec.camera_preview/GuiResizerTopLeft.svg b/addons/anthonyec.camera_preview/GuiResizerTopLeft.svg new file mode 100644 index 0000000..fe4dbf5 --- /dev/null +++ b/addons/anthonyec.camera_preview/GuiResizerTopLeft.svg @@ -0,0 +1 @@ + diff --git a/addons/anthonyec.camera_preview/GuiResizerTopLeft.svg.import b/addons/anthonyec.camera_preview/GuiResizerTopLeft.svg.import new file mode 100644 index 0000000..9584d3b --- /dev/null +++ b/addons/anthonyec.camera_preview/GuiResizerTopLeft.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://btc01wc11tiid" +path="res://.godot/imported/GuiResizerTopLeft.svg-eb563f557424c74239e878a1213a5bf4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/anthonyec.camera_preview/GuiResizerTopLeft.svg" +dest_files=["res://.godot/imported/GuiResizerTopLeft.svg-eb563f557424c74239e878a1213a5bf4.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/anthonyec.camera_preview/GuiResizerTopRight.svg b/addons/anthonyec.camera_preview/GuiResizerTopRight.svg new file mode 100644 index 0000000..dd00953 --- /dev/null +++ b/addons/anthonyec.camera_preview/GuiResizerTopRight.svg @@ -0,0 +1 @@ + diff --git a/addons/anthonyec.camera_preview/GuiResizerTopRight.svg.import b/addons/anthonyec.camera_preview/GuiResizerTopRight.svg.import new file mode 100644 index 0000000..4a1fa5d --- /dev/null +++ b/addons/anthonyec.camera_preview/GuiResizerTopRight.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://04l05jxuyt7k" +path="res://.godot/imported/GuiResizerTopRight.svg-cc1dc8556d51357c5eb0b01d09d8f049.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/anthonyec.camera_preview/GuiResizerTopRight.svg" +dest_files=["res://.godot/imported/GuiResizerTopRight.svg-cc1dc8556d51357c5eb0b01d09d8f049.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/anthonyec.camera_preview/Pin.svg b/addons/anthonyec.camera_preview/Pin.svg new file mode 100644 index 0000000..8e5935c --- /dev/null +++ b/addons/anthonyec.camera_preview/Pin.svg @@ -0,0 +1 @@ + diff --git a/addons/anthonyec.camera_preview/Pin.svg.import b/addons/anthonyec.camera_preview/Pin.svg.import new file mode 100644 index 0000000..27d274f --- /dev/null +++ b/addons/anthonyec.camera_preview/Pin.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://do6d60od41vmg" +path="res://.godot/imported/Pin.svg-83b09f5c00a829c5d8b136bf5bae65bc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/anthonyec.camera_preview/Pin.svg" +dest_files=["res://.godot/imported/Pin.svg-83b09f5c00a829c5d8b136bf5bae65bc.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/anthonyec.camera_preview/plugin.cfg b/addons/anthonyec.camera_preview/plugin.cfg new file mode 100644 index 0000000..4ad0d4c --- /dev/null +++ b/addons/anthonyec.camera_preview/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Little Camera Preview" +description="Shows a picture-in-picture preview of the selected 2D or 3D camera" +author="Anthony Cossins" +version="1.3" +script="plugin.gd" diff --git a/addons/anthonyec.camera_preview/plugin.gd b/addons/anthonyec.camera_preview/plugin.gd new file mode 100644 index 0000000..4e74dd8 --- /dev/null +++ b/addons/anthonyec.camera_preview/plugin.gd @@ -0,0 +1,87 @@ +@tool +extends EditorPlugin + +const preview_scene = preload("res://addons/anthonyec.camera_preview/preview.tscn") + +var preview: CameraPreview +var current_main_screen_name: String + +func _enter_tree() -> void: + main_screen_changed.connect(_on_main_screen_changed) + EditorInterface.get_selection().selection_changed.connect(_on_editor_selection_changed) + + # Initialise preview panel and add to main screen. + preview = preview_scene.instantiate() as CameraPreview + preview.request_hide() + + var main_screen = EditorInterface.get_editor_main_screen() + main_screen.add_child(preview) + +func _exit_tree() -> void: + if preview: + preview.queue_free() + +func _ready() -> void: + # TODO: Currently there is no API to get the main screen name without + # listening to the `EditorPlugin.main_screen_changed` signal: + # https://github.com/godotengine/godot-proposals/issues/2081 + EditorInterface.set_main_screen_editor("Script") + EditorInterface.set_main_screen_editor("3D") + +func _on_main_screen_changed(screen_name: String) -> void: + current_main_screen_name = screen_name + + # TODO: Bit of a hack to prevent pinned staying between view changes on the same scene. + preview.unlink_camera() + _on_editor_selection_changed() + +func _on_editor_selection_changed() -> void: + if not is_main_screen_viewport(): + # This hides the preview "container" and not the preview itself, allowing + # any locked previews to remain visible once switching back to 3D tab. + preview.visible = false + return + + preview.visible = true + + var selected_nodes = EditorInterface.get_selection().get_selected_nodes() + + var selected_camera_3d: Camera3D = find_camera_3d_or_null(selected_nodes) + var selected_camera_2d: Camera2D = find_camera_2d_or_null(selected_nodes) + + if selected_camera_3d and current_main_screen_name == "3D": + preview.link_with_camera_3d(selected_camera_3d) + preview.request_show() + + elif selected_camera_2d and current_main_screen_name == "2D": + preview.link_with_camera_2d(selected_camera_2d) + preview.request_show() + + else: + preview.request_hide() + +func is_main_screen_viewport() -> bool: + return current_main_screen_name == "3D" or current_main_screen_name == "2D" + +func find_camera_3d_or_null(nodes: Array[Node]) -> Camera3D: + var camera: Camera3D + + for node in nodes: + if node is Camera3D: + camera = node as Camera3D + break + + return camera + +func find_camera_2d_or_null(nodes: Array[Node]) -> Camera2D: + var camera: Camera2D + + for node in nodes: + if node is Camera2D: + camera = node as Camera2D + break + + return camera + +func _on_selected_camera_3d_tree_exiting() -> void: + preview.unlink_camera() diff --git a/addons/anthonyec.camera_preview/preview.gd b/addons/anthonyec.camera_preview/preview.gd new file mode 100644 index 0000000..3c07d04 --- /dev/null +++ b/addons/anthonyec.camera_preview/preview.gd @@ -0,0 +1,404 @@ +@tool + +class_name CameraPreview +extends Control + +enum CameraType { + CAMERA_2D, + CAMERA_3D +} + +enum PinnedPosition { + LEFT, + RIGHT, +} + +enum InteractionState { + NONE, + RESIZE, + DRAG, + + # Animation is split into 2 seperate states so that the tween is only + # invoked once in the "start" state. + START_ANIMATE_INTO_PLACE, + ANIMATE_INTO_PLACE, +} + +const margin_3d: Vector2 = Vector2(10, 10) +const margin_2d: Vector2 = Vector2(20, 15) +const panel_margin: float = 2 +const min_panel_size: float = 250 + +@onready var panel: Panel = %Panel +@onready var placeholder: Panel = %Placeholder +@onready var preview_camera_3d: Camera3D = %Camera3D +@onready var preview_camera_2d: Camera2D = %Camera2D +@onready var sub_viewport: SubViewport = %SubViewport +@onready var sub_viewport_text_rect: TextureRect = %TextureRect +@onready var resize_left_handle: Button = %ResizeLeftHandle +@onready var resize_right_handle: Button = %ResizeRightHandle +@onready var lock_button: Button = %LockButton +@onready var gradient: TextureRect = %Gradient +@onready var viewport_margin_container: MarginContainer = %ViewportMarginContainer +@onready var overlay_margin_container: MarginContainer = %OverlayMarginContainer +@onready var overlay_container: Control = %OverlayContainer + +var camera_type: CameraType = CameraType.CAMERA_3D +var pinned_position: PinnedPosition = PinnedPosition.RIGHT +var viewport_ratio: float = 1 +var editor_scale: float = EditorInterface.get_editor_scale() +var is_locked: bool +var show_controls: bool +var selected_camera_3d: Camera3D +var selected_camera_2d: Camera2D + +var state: InteractionState = InteractionState.NONE +var initial_mouse_position: Vector2 +var initial_panel_size: Vector2 +var initial_panel_position: Vector2 + +func _ready() -> void: + # Set initial width. + panel.size.x = min_panel_size * editor_scale + + # Setting texture to viewport in code instead of directly in the editor + # because otherwise an error "Path to node is invalid: Panel/SubViewport" + # on first load. This is harmless but doesn't look great. + # + # This is a known issue: + # https://github.com/godotengine/godot/issues/27790#issuecomment-499740220 + sub_viewport_text_rect.texture = sub_viewport.get_texture() + + # From what I can tell there's something wrong with how an editor theme + # scales when used within a plugin. It seems to ignore the screen scale. + # For instance, a 30x30px button will appear tiny on a retina display. + # + # Someone else had the issue with no luck: + # https://forum.godotengine.org/t/how-to-scale-plugin-controls-to-look-the-same-in-4k-as-1080p/36151 + # + # And seems Dialogic also scales buttons manually: + # https://github.com/dialogic-godot/dialogic/blob/master/addons/dialogic/Editor/Common/sidebar.gd#L25C6-L38 + # + # Maybe I don't know the correct way to do it, so for now the workaround is + # to set the correct size in code using screen scale. + var button_size = Vector2(30, 30) * editor_scale + var margin_size: float = panel_margin * editor_scale + + resize_left_handle.size = button_size + resize_left_handle.pivot_offset = Vector2(0, 0) * editor_scale + + resize_right_handle.size = button_size + resize_right_handle.pivot_offset = Vector2(30, 30) * editor_scale + + lock_button.size = button_size + lock_button.pivot_offset = Vector2(0, 30) * editor_scale + + viewport_margin_container.add_theme_constant_override("margin_left", margin_size) + viewport_margin_container.add_theme_constant_override("margin_top", margin_size) + viewport_margin_container.add_theme_constant_override("margin_right", margin_size) + viewport_margin_container.add_theme_constant_override("margin_bottom", margin_size) + + overlay_margin_container.add_theme_constant_override("margin_left", margin_size) + overlay_margin_container.add_theme_constant_override("margin_top", margin_size) + overlay_margin_container.add_theme_constant_override("margin_right", margin_size) + overlay_margin_container.add_theme_constant_override("margin_bottom", margin_size) + + # Parent node overlay size is not available on first ready, need to wait a + # frame for it to be drawn. + await get_tree().process_frame + + # Anchors are set in code because setting them in the editor UI doesn't take + # editor scale into account. + resize_left_handle.position = Vector2(0, 0) + resize_right_handle.set_anchors_preset(Control.PRESET_TOP_LEFT) + + resize_right_handle.position = Vector2(overlay_container.size.x - button_size.x, 0) + resize_right_handle.set_anchors_preset(Control.PRESET_TOP_RIGHT) + + lock_button.position = Vector2(0, overlay_container.size.y - button_size.y) + lock_button.set_anchors_preset(Control.PRESET_BOTTOM_LEFT) + +func _process(_delta: float) -> void: + if not visible: return + + match state: + InteractionState.NONE: + panel.size = get_clamped_size(panel.size) + panel.position = get_pinned_position(pinned_position) + + InteractionState.RESIZE: + var delta_mouse_position = initial_mouse_position - get_global_mouse_position() + var resized_size = panel.size + + if pinned_position == PinnedPosition.LEFT: + resized_size = initial_panel_size - delta_mouse_position + + if pinned_position == PinnedPosition.RIGHT: + resized_size = initial_panel_size + delta_mouse_position + + panel.size = get_clamped_size(resized_size) + panel.position = get_pinned_position(pinned_position) + + InteractionState.DRAG: + placeholder.size = panel.size + + var global_mouse_position = get_global_mouse_position() + var offset = initial_mouse_position - initial_panel_position + + panel.global_position = global_mouse_position - offset + + if global_mouse_position.x < global_position.x + size.x / 2: + pinned_position = PinnedPosition.LEFT + else: + pinned_position = PinnedPosition.RIGHT + + placeholder.position = get_pinned_position(pinned_position) + + InteractionState.START_ANIMATE_INTO_PLACE: + var final_position: Vector2 = get_pinned_position(pinned_position) + var tween = get_tree().create_tween() + + tween.set_ease(Tween.EASE_OUT) + tween.set_trans(Tween.TRANS_CUBIC) + tween.tween_property(panel, "position", final_position, 0.3) + + tween.finished.connect(func(): + panel.position = final_position + state = InteractionState.NONE + ) + + state = InteractionState.ANIMATE_INTO_PLACE + + # I couldn't get `mouse_entered` and `mouse_exited` events to work + # nicely, so I use rect method instead. Plus using this method it's easy to + # grow the hit area size. + var panel_hover_rect = Rect2(panel.global_position, panel.size) + panel_hover_rect = panel_hover_rect.grow(40) + + var mouse_position = get_global_mouse_position() + + show_controls = state != InteractionState.NONE or panel_hover_rect.has_point(mouse_position) + + # UI visibility. + resize_left_handle.visible = show_controls and pinned_position == PinnedPosition.RIGHT + resize_right_handle.visible = show_controls and pinned_position == PinnedPosition.LEFT + lock_button.visible = show_controls or is_locked + placeholder.visible = state == InteractionState.DRAG or state == InteractionState.ANIMATE_INTO_PLACE + gradient.visible = show_controls + + # Sync camera settings. + if camera_type == CameraType.CAMERA_3D and selected_camera_3d: + sub_viewport.size = panel.size + + # Sync position and rotation without using a `RemoteTransform` node + # because if you save a camera as a scene, the remote transform node will + # be stored within the scene. Also it's harder to keep the remote + # transform `remote_path` up-to-date with scene changes, which causes + # many errors. + preview_camera_3d.global_position = selected_camera_3d.global_position + preview_camera_3d.global_rotation = selected_camera_3d.global_rotation + + preview_camera_3d.fov = selected_camera_3d.fov + preview_camera_3d.projection = selected_camera_3d.projection + preview_camera_3d.size = selected_camera_3d.size + preview_camera_3d.cull_mask = selected_camera_3d.cull_mask + preview_camera_3d.keep_aspect = selected_camera_3d.keep_aspect + preview_camera_3d.near = selected_camera_3d.near + preview_camera_3d.far = selected_camera_3d.far + preview_camera_3d.h_offset = selected_camera_3d.h_offset + preview_camera_3d.v_offset = selected_camera_3d.v_offset + preview_camera_3d.attributes = selected_camera_3d.attributes + preview_camera_3d.environment = selected_camera_3d.environment + + if camera_type == CameraType.CAMERA_2D and selected_camera_2d: + var project_window_size = get_project_window_size() + var ratio = project_window_size.x / panel.size.x + + # TODO: Is there a better way to fix this? + # The camera border is visible sometimes due to pixel rounding. + # Subtract 1px from right and bottom to hide this. + var hide_camera_border_fix = Vector2(1, 1) + + sub_viewport.size = panel.size + sub_viewport.size_2d_override = (panel.size - hide_camera_border_fix) * ratio + sub_viewport.size_2d_override_stretch = true + + preview_camera_2d.global_position = selected_camera_2d.global_position + preview_camera_2d.global_rotation = selected_camera_2d.global_rotation + + preview_camera_2d.offset = selected_camera_2d.offset + preview_camera_2d.zoom = selected_camera_2d.zoom + preview_camera_2d.ignore_rotation = selected_camera_2d.ignore_rotation + preview_camera_2d.anchor_mode = selected_camera_2d.anchor_mode + preview_camera_2d.limit_left = selected_camera_2d.limit_left + preview_camera_2d.limit_right = selected_camera_2d.limit_right + preview_camera_2d.limit_top = selected_camera_2d.limit_top + preview_camera_2d.limit_bottom = selected_camera_2d.limit_bottom + +func link_with_camera_3d(camera_3d: Camera3D) -> void: + # TODO: Camera may not be ready since this method is called in `_enter_tree` + # in the plugin because of a workaround for: + # https://github.com/godotengine/godot-proposals/issues/2081 + if not preview_camera_3d: + return request_hide() + + var is_different_camera = camera_3d != preview_camera_3d + + # TODO: A bit messy. + if is_different_camera: + if preview_camera_3d.tree_exiting.is_connected(unlink_camera): + preview_camera_3d.tree_exiting.disconnect(unlink_camera) + + if not camera_3d.tree_exiting.is_connected(unlink_camera): + camera_3d.tree_exiting.connect(unlink_camera) + + sub_viewport.disable_3d = false + sub_viewport.world_3d = camera_3d.get_world_3d() + + selected_camera_3d = camera_3d + camera_type = CameraType.CAMERA_3D + +func link_with_camera_2d(camera_2d: Camera2D) -> void: + if not preview_camera_2d: + return request_hide() + + var is_different_camera = camera_2d != preview_camera_2d + + # TODO: A bit messy. + if is_different_camera: + if preview_camera_2d.tree_exiting.is_connected(unlink_camera): + preview_camera_2d.tree_exiting.disconnect(unlink_camera) + + if not camera_2d.tree_exiting.is_connected(unlink_camera): + camera_2d.tree_exiting.connect(unlink_camera) + + sub_viewport.disable_3d = true + sub_viewport.world_2d = camera_2d.get_world_2d() + + selected_camera_2d = camera_2d + camera_type = CameraType.CAMERA_2D + +func unlink_camera() -> void: + if selected_camera_3d: + selected_camera_3d = null + + if selected_camera_2d: + selected_camera_2d = null + + is_locked = false + lock_button.button_pressed = false + +func request_hide() -> void: + if is_locked: return + visible = false + +func request_show() -> void: + visible = true + +func get_pinned_position(pinned_position: PinnedPosition) -> Vector2: + var margin: Vector2 = margin_3d * editor_scale + + if camera_type == CameraType.CAMERA_2D: + margin = margin_2d * editor_scale + + match pinned_position: + PinnedPosition.LEFT: + return Vector2.ZERO - Vector2(0, panel.size.y) - Vector2(-margin.x, margin.y) + PinnedPosition.RIGHT: + return size - panel.size - margin + _: + assert(false, "Unknown pinned position %s" % str(pinned_position)) + + return Vector2.ZERO + +func get_clamped_size(desired_size: Vector2) -> Vector2: + var viewport_ratio = get_project_window_ratio() + var editor_viewport_size = get_editor_viewport_size() + + var max_bounds = Vector2( + editor_viewport_size.x * 0.6, + editor_viewport_size.y * 0.8 + ) + + var clamped_size = desired_size + + # Apply aspect ratio. + clamped_size = Vector2(clamped_size.x, clamped_size.x * viewport_ratio) + + # Clamp the max size while respecting the aspect ratio. + if clamped_size.y >= max_bounds.y: + clamped_size.x = max_bounds.y / viewport_ratio + clamped_size.y = max_bounds.y + + if clamped_size.x >= max_bounds.x: + clamped_size.x = max_bounds.x + clamped_size.y = max_bounds.x * viewport_ratio + + # Clamp the min size based on if it's portrait or landscape. Portrait min + # size should be based on it's height. Landscape min size is based on it's + # width instead. Applying min width to a portrait size would make it too big. + var is_portrait = viewport_ratio > 1 + + if is_portrait and clamped_size.y <= min_panel_size * editor_scale: + clamped_size.x = min_panel_size / viewport_ratio + clamped_size.y = min_panel_size + clamped_size = clamped_size * editor_scale + + if not is_portrait and clamped_size.x <= min_panel_size * editor_scale: + clamped_size.x = min_panel_size + clamped_size.y = min_panel_size * viewport_ratio + clamped_size = clamped_size * editor_scale + + # Round down to avoid sub-pixel artifacts, mainly seen around the margins. + return clamped_size.floor() + +func get_project_window_size() -> Vector2: + var window_width = float(ProjectSettings.get_setting("display/window/size/viewport_width")) + var window_height = float(ProjectSettings.get_setting("display/window/size/viewport_height")) + + return Vector2(window_width, window_height) + +func get_project_window_ratio() -> float: + var project_window_size = get_project_window_size() + + return project_window_size.y / project_window_size.x + +func get_editor_viewport_size() -> Vector2: + var fallback_size = EditorInterface.get_editor_main_screen().size + + # There isn't an API for getting the viewport node. Instead it has to be + # found by checking the parent's parent of the subviewport and find + # the correct node based on name and class. + var editor_sub_viewport_3d = EditorInterface.get_editor_viewport_3d(0) + var editor_viewport_container = editor_sub_viewport_3d.get_parent().get_parent().get_parent() + + # Early return incase editor tree structure has changed. + if editor_viewport_container.get_class() != "Node3DEditorViewportContainer": + return fallback_size + + return editor_viewport_container.size + +func _on_resize_handle_button_down() -> void: + if state != InteractionState.NONE: return + + state = InteractionState.RESIZE + initial_mouse_position = get_global_mouse_position() + initial_panel_size = panel.size + +func _on_resize_handle_button_up() -> void: + state = InteractionState.NONE + +func _on_drag_handle_button_down() -> void: + if state != InteractionState.NONE: return + + state = InteractionState.DRAG + initial_mouse_position = get_global_mouse_position() + initial_panel_position = panel.global_position + +func _on_drag_handle_button_up() -> void: + if state != InteractionState.DRAG: return + + state = InteractionState.START_ANIMATE_INTO_PLACE + +func _on_lock_button_pressed() -> void: + is_locked = !is_locked diff --git a/addons/anthonyec.camera_preview/preview.tscn b/addons/anthonyec.camera_preview/preview.tscn new file mode 100644 index 0000000..77b3ced --- /dev/null +++ b/addons/anthonyec.camera_preview/preview.tscn @@ -0,0 +1,200 @@ +[gd_scene load_steps=8 format=3 uid="uid://xybmfvufjuv"] + +[ext_resource type="Script" path="res://addons/anthonyec.camera_preview/preview.gd" id="1_6b32r"] +[ext_resource type="Texture2D" uid="uid://do6d60od41vmg" path="res://addons/anthonyec.camera_preview/Pin.svg" id="2_p0pa8"] +[ext_resource type="Texture2D" uid="uid://btc01wc11tiid" path="res://addons/anthonyec.camera_preview/GuiResizerTopLeft.svg" id="2_t64ej"] +[ext_resource type="Texture2D" uid="uid://04l05jxuyt7k" path="res://addons/anthonyec.camera_preview/GuiResizerTopRight.svg" id="3_6yuab"] + +[sub_resource type="ViewportTexture" id="ViewportTexture_hchdq"] +viewport_path = NodePath("Panel/SubViewport") + +[sub_resource type="Gradient" id="Gradient_11p6r"] +offsets = PackedFloat32Array(0, 0.3, 0.6, 1) +colors = PackedColorArray(0, 0, 0, 0.235294, 0, 0, 0, 0.0784314, 0, 0, 0, 0.0784314, 0, 0, 0, 0.235294) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_4dkve"] +gradient = SubResource("Gradient_11p6r") +width = 256 +height = 256 +fill_to = Vector2(2.08165e-12, 1) + +[node name="Preview" type="Control"] +z_index = 999 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_6b32r") + +[node name="Placeholder" type="Panel" parent="."] +unique_name_in_owner = true +visible = false +modulate = Color(1, 1, 1, 0.705882) +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -40.0 +offset_top = -40.0 +offset_right = 410.0 +offset_bottom = 410.0 +grow_horizontal = 0 +grow_vertical = 0 + +[node name="Panel" type="Panel" parent="."] +unique_name_in_owner = true +clip_contents = true +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -520.0 +offset_top = -908.889 +offset_right = -20.0 +offset_bottom = -20.0 +grow_horizontal = 0 +grow_vertical = 0 +pivot_offset = Vector2(450, 300) + +[node name="SubViewport" type="SubViewport" parent="Panel"] +unique_name_in_owner = true +handle_input_locally = false +gui_disable_input = true +size_2d_override_stretch = true + +[node name="Camera3D" type="Camera3D" parent="Panel/SubViewport"] +unique_name_in_owner = true +current = true + +[node name="Camera2D" type="Camera2D" parent="Panel/SubViewport"] +unique_name_in_owner = true +ignore_rotation = false + +[node name="ViewportMarginContainer" type="MarginContainer" parent="Panel"] +unique_name_in_owner = true +clip_contents = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="TextureRect" type="TextureRect" parent="Panel/ViewportMarginContainer"] +unique_name_in_owner = true +layout_mode = 2 +texture = SubResource("ViewportTexture_hchdq") +expand_mode = 1 + +[node name="Gradient" type="TextureRect" parent="Panel"] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = SubResource("GradientTexture2D_4dkve") + +[node name="OverlayMarginContainer" type="MarginContainer" parent="Panel"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="OverlayContainer" type="Control" parent="Panel/OverlayMarginContainer"] +unique_name_in_owner = true +clip_contents = true +layout_mode = 2 +mouse_filter = 2 + +[node name="DragHandle" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +focus_mode = 0 +flat = true + +[node name="ResizeLeftHandle" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 1 +offset_right = 60.0 +offset_bottom = 60.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +mouse_default_cursor_shape = 12 +icon = ExtResource("2_t64ej") +flat = true +icon_alignment = 1 +expand_icon = true + +[node name="ResizeRightHandle" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -60.0 +offset_bottom = 60.0 +pivot_offset = Vector2(60, 60) +size_flags_horizontal = 8 +size_flags_vertical = 0 +mouse_default_cursor_shape = 11 +icon = ExtResource("3_6yuab") +flat = true +icon_alignment = 1 +expand_icon = true + +[node name="LockButton" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -60.0 +offset_right = 60.0 +pivot_offset = Vector2(0, 60) +size_flags_horizontal = 0 +size_flags_vertical = 8 +tooltip_text = "Always Show Preview" +toggle_mode = true +icon = ExtResource("2_p0pa8") +flat = true +icon_alignment = 1 +expand_icon = true + +[connection signal="button_down" from="Panel/OverlayMarginContainer/OverlayContainer/DragHandle" to="." method="_on_drag_handle_button_down"] +[connection signal="button_up" from="Panel/OverlayMarginContainer/OverlayContainer/DragHandle" to="." method="_on_drag_handle_button_up"] +[connection signal="renamed" from="Panel/OverlayMarginContainer/OverlayContainer/DragHandle" to="." method="_on_drag_handle_renamed"] +[connection signal="button_down" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeLeftHandle" to="." method="_on_resize_handle_button_down"] +[connection signal="button_up" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeLeftHandle" to="." method="_on_resize_handle_button_up"] +[connection signal="button_down" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeRightHandle" to="." method="_on_resize_handle_button_down"] +[connection signal="button_up" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeRightHandle" to="." method="_on_resize_handle_button_up"] +[connection signal="pressed" from="Panel/OverlayMarginContainer/OverlayContainer/LockButton" to="." method="_on_lock_button_pressed"] diff --git a/assets/Textures/ObjectTextures/Blunderbus.png b/assets/Textures/ObjectTextures/Blunderbus.png new file mode 100644 index 0000000..96f9371 Binary files /dev/null and b/assets/Textures/ObjectTextures/Blunderbus.png differ diff --git a/assets/Textures/ObjectTextures/Blunderbus.png.import b/assets/Textures/ObjectTextures/Blunderbus.png.import new file mode 100644 index 0000000..b867fd6 --- /dev/null +++ b/assets/Textures/ObjectTextures/Blunderbus.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://74id2drhfp2s" +path="res://.godot/imported/Blunderbus.png-655ba7bc5de64378bbd28fc0db8c9b24.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Textures/ObjectTextures/Blunderbus.png" +dest_files=["res://.godot/imported/Blunderbus.png-655ba7bc5de64378bbd28fc0db8c9b24.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 diff --git a/assets/Textures/ObjectTextures/Pistol.png b/assets/Textures/ObjectTextures/Pistol.png new file mode 100644 index 0000000..b5f45f8 Binary files /dev/null and b/assets/Textures/ObjectTextures/Pistol.png differ diff --git a/assets/Textures/ObjectTextures/Pistol.png.import b/assets/Textures/ObjectTextures/Pistol.png.import new file mode 100644 index 0000000..765337d --- /dev/null +++ b/assets/Textures/ObjectTextures/Pistol.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2fic5txnwu3u" +path="res://.godot/imported/Pistol.png-088d61fee53cc956a8ad21cb8c0cb860.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Textures/ObjectTextures/Pistol.png" +dest_files=["res://.godot/imported/Pistol.png-088d61fee53cc956a8ad21cb8c0cb860.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 diff --git a/assets/Textures/ObjectTextures/RocketLauncher.png b/assets/Textures/ObjectTextures/RocketLauncher.png new file mode 100644 index 0000000..6c4ac5b Binary files /dev/null and b/assets/Textures/ObjectTextures/RocketLauncher.png differ diff --git a/assets/Textures/ObjectTextures/RocketLauncher.png.import b/assets/Textures/ObjectTextures/RocketLauncher.png.import new file mode 100644 index 0000000..c10e4f8 --- /dev/null +++ b/assets/Textures/ObjectTextures/RocketLauncher.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dyvcljaoux8h" +path="res://.godot/imported/RocketLauncher.png-d6d9f4dd5ce1e4a1f9b18f5bb63728dd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Textures/ObjectTextures/RocketLauncher.png" +dest_files=["res://.godot/imported/RocketLauncher.png-d6d9f4dd5ce1e4a1f9b18f5bb63728dd.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 diff --git a/assets/Textures/ObjectTextures/mac10.png b/assets/Textures/ObjectTextures/mac10.png new file mode 100644 index 0000000..fc7ace0 Binary files /dev/null and b/assets/Textures/ObjectTextures/mac10.png differ diff --git a/assets/Textures/ObjectTextures/mac10.png.import b/assets/Textures/ObjectTextures/mac10.png.import new file mode 100644 index 0000000..686101a --- /dev/null +++ b/assets/Textures/ObjectTextures/mac10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gx3iw54iemho" +path="res://.godot/imported/mac10.png-01420520bd1372fc6a82121c21a6d814.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Textures/ObjectTextures/mac10.png" +dest_files=["res://.godot/imported/mac10.png-01420520bd1372fc6a82121c21a6d814.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 diff --git a/assets/Textures/ObjectTextures/revolver1.png b/assets/Textures/ObjectTextures/revolver1.png new file mode 100644 index 0000000..b910e7d Binary files /dev/null and b/assets/Textures/ObjectTextures/revolver1.png differ diff --git a/assets/Textures/ObjectTextures/revolver1.png.import b/assets/Textures/ObjectTextures/revolver1.png.import new file mode 100644 index 0000000..416aeda --- /dev/null +++ b/assets/Textures/ObjectTextures/revolver1.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bho7c8s2yno12" +path="res://.godot/imported/revolver1.png-2275678462fdf0863e5d71c28157a203.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Textures/ObjectTextures/revolver1.png" +dest_files=["res://.godot/imported/revolver1.png-2275678462fdf0863e5d71c28157a203.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 diff --git a/assets/blockout_2.tscn b/assets/blockout_2.tscn index 0903a9f..1eed322 100644 --- a/assets/blockout_2.tscn +++ b/assets/blockout_2.tscn @@ -897,6 +897,7 @@ _data = { [node name="BLOCKOUT2Test" type="Node3D" node_paths=PackedStringArray("player")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.016016, 0.0225029, -0.0192337) script = ExtResource("1_sbpvn") +load_save = false player = NodePath("Player") money = 50 start_health = 5 diff --git a/assets/mac_10.tscn b/assets/mac_10.tscn index cd17fe3..ec5a80a 100644 --- a/assets/mac_10.tscn +++ b/assets/mac_10.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=33 format=4 uid="uid://brl0bsqjl5dg3"] +[gd_scene load_steps=34 format=4 uid="uid://brl0bsqjl5dg3"] [ext_resource type="PackedScene" uid="uid://c33b6ldlxxfro" path="res://assets/Models/mac10.blend" id="1_nb4p5"] [ext_resource type="Script" path="res://scripts/gun.gd" id="2_tskiy"] [ext_resource type="PackedScene" uid="uid://nq5nq2hjc4ec" path="res://assets/bullet_fake.tscn" id="3_heo3y"] +[ext_resource type="Texture2D" uid="uid://gx3iw54iemho" path="res://assets/Textures/ObjectTextures/mac10.png" id="3_p1hxc"] [ext_resource type="PackedScene" uid="uid://dqhltdnqyg8ni" path="res://assets/bullet.tscn" id="3_w1kko"] [ext_resource type="PackedScene" uid="uid://crvohhc6kgshn" path="res://assets/bullet_hole.tscn" id="4_eleuq"] [ext_resource type="PackedScene" uid="uid://cp8563f0oxvff" path="res://assets/mag1.tscn" id="4_ji2hu"] @@ -489,6 +490,7 @@ _data = { [node name="mac10" node_paths=PackedStringArray("r_hand_location", "l_hand_location", "flare_light", "anim_player", "barrel_raycast", "casing_ejector", "mag_ejector", "audio_fire", "audio_empty", "audio_reload") instance=ExtResource("1_nb4p5")] script = ExtResource("2_tskiy") gun_name = "Mac 10" +gun_icon = ExtResource("3_p1hxc") fov_zoom_amt = 0.998 recoil_amount = Vector3(0.02, 0.05, 0.05) max_ammo = 20 diff --git a/assets/pistol1.tscn b/assets/pistol1.tscn index 1101088..2cae13d 100644 --- a/assets/pistol1.tscn +++ b/assets/pistol1.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=23 format=3 uid="uid://dslxb3psx30vp"] +[gd_scene load_steps=24 format=3 uid="uid://dslxb3psx30vp"] [ext_resource type="PackedScene" uid="uid://svrb3n31mkag" path="res://assets/Models/gun.blend" id="1_frekg"] [ext_resource type="Script" path="res://scripts/trackerGun.gd" id="2_ieev5"] +[ext_resource type="Texture2D" uid="uid://d2fic5txnwu3u" path="res://assets/Textures/ObjectTextures/Pistol.png" id="3_gkvbi"] [ext_resource type="PackedScene" uid="uid://crvohhc6kgshn" path="res://assets/bullet_hole.tscn" id="4_bu1g0"] [ext_resource type="PackedScene" uid="uid://c1gdehrsytlkk" path="res://assets/casing.tscn" id="5_gls8p"] [ext_resource type="PackedScene" uid="uid://cp8563f0oxvff" path="res://assets/mag1.tscn" id="6_ysonb"] @@ -431,6 +432,7 @@ _data = { transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0145504, -0.0460228) script = ExtResource("2_ieev5") gun_name = "Tracker Pistol" +gun_icon = ExtResource("3_gkvbi") recoil_amount = Vector3(0, 0.05, 0.05) bullet_speed = 50 tracker_indicator = NodePath("gun/slide/TrackerIndicator") diff --git a/assets/player.tscn b/assets/player.tscn index 8058763..de53746 100644 --- a/assets/player.tscn +++ b/assets/player.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=31 format=3 uid="uid://drwae3loscbw7"] +[gd_scene load_steps=32 format=3 uid="uid://drwae3loscbw7"] [ext_resource type="Script" path="res://scripts/player.gd" id="1_x7wms"] [ext_resource type="Script" path="res://scripts/recoil.gd" id="3_405jc"] [ext_resource type="Texture2D" uid="uid://cknftvqq8rbrm" path="res://assets/Textures/Cookie_tutorial_texture_flashlight.png" id="4_x670l"] +[ext_resource type="PackedScene" uid="uid://dqgtnykkbngem" path="res://assets/weapon_select.tscn" id="5_bvbcl"] [ext_resource type="PackedScene" uid="uid://br882tlh3cfwu" path="res://hud.tscn" id="5_yenaw"] [ext_resource type="AudioStream" uid="uid://bki17g7j4kqn4" path="res://assets/Audio/PickupSound Mixdown 3.wav" id="8_dwqsx"] [ext_resource type="Script" path="res://scripts/bullet_ray.gd" id="10_ektr6"] @@ -142,6 +143,10 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.437954, -1) stream = ExtResource("14_pnsbm") volume_db = 2.0 +[node name="WeaponSelect" parent="Head/Recoil/Camera3D" instance=ExtResource("5_bvbcl")] +visible = false +inner_radius = 256 + [node name="HUD" parent="Head/Recoil/Camera3D" instance=ExtResource("5_yenaw")] [node name="GunRay" type="RayCast3D" parent="Head/Recoil/Camera3D" groups=["gun_ray"]] diff --git a/assets/revolver_1.tscn b/assets/revolver_1.tscn index a28b28d..78ad342 100644 --- a/assets/revolver_1.tscn +++ b/assets/revolver_1.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=67 format=4 uid="uid://b5eclfg0cmmal"] +[gd_scene load_steps=68 format=4 uid="uid://b5eclfg0cmmal"] [ext_resource type="PackedScene" uid="uid://dgogd08c0ubt6" path="res://assets/Models/revolver1.blend" id="1_i5f84"] [ext_resource type="Script" path="res://scripts/revolver_1.gd" id="2_7rsti"] [ext_resource type="PackedScene" uid="uid://dqhltdnqyg8ni" path="res://assets/bullet.tscn" id="3_32prk"] +[ext_resource type="Texture2D" uid="uid://bho7c8s2yno12" path="res://assets/Textures/ObjectTextures/revolver1.png" id="3_nl201"] [ext_resource type="Texture2D" uid="uid://dtg3nb2ew72c3" path="res://assets/star_05.png" id="3_q41fl"] [ext_resource type="PackedScene" uid="uid://crvohhc6kgshn" path="res://assets/bullet_hole.tscn" id="4_ubqgq"] [ext_resource type="PackedScene" uid="uid://c1gdehrsytlkk" path="res://assets/casing.tscn" id="5_m3vsl"] @@ -1066,6 +1067,7 @@ _data = { transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0718293, 0) script = ExtResource("2_7rsti") gun_name = ".44 Galore" +gun_icon = ExtResource("3_nl201") fire_mode = 1 fov_zoom_amt = 0.99 recoil_amount = Vector3(0.25, 0.1, 0.1) diff --git a/assets/rocket_launcher.tscn b/assets/rocket_launcher.tscn index a3c8960..54cd5f7 100644 --- a/assets/rocket_launcher.tscn +++ b/assets/rocket_launcher.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=32 format=4 uid="uid://2o2wcc5i1al4"] +[gd_scene load_steps=33 format=4 uid="uid://2o2wcc5i1al4"] [ext_resource type="Texture2D" uid="uid://b82yqx4tml6hn" path="res://assets/Models/rocketlauncher1.rough.png" id="1_b5b37"] [ext_resource type="Script" path="res://scripts/rocket_launcher.gd" id="1_ra4f1"] +[ext_resource type="Texture2D" uid="uid://dyvcljaoux8h" path="res://assets/Textures/ObjectTextures/RocketLauncher.png" id="2_41bg8"] [ext_resource type="PackedScene" uid="uid://hptaoyu5jeqk" path="res://assets/rocket.tscn" id="2_dmokb"] [ext_resource type="Texture2D" uid="uid://c2hi7c5hl2yk2" path="res://assets/Models/rocketlauncher1.normal.png" id="2_y5wa3"] [ext_resource type="AudioStream" uid="uid://dp71xac3vbsob" path="res://assets/Audio/Weapons/rocket-launcher-firing-SBA-300109793.wav" id="5_i3755"] @@ -457,6 +458,7 @@ _data = { [node name="RocketLauncher" type="Node3D" node_paths=PackedStringArray("anim_player", "barrel_raycast", "mag_ejector", "audio_fire", "audio_empty", "audio_reload")] script = ExtResource("1_ra4f1") gun_name = "Badooka" +gun_icon = ExtResource("2_41bg8") fire_mode = 1 max_ammo = 1 bullet_speed = 60.0 diff --git a/assets/spider2.tscn b/assets/spider2.tscn index 3b5a73c..5943538 100644 --- a/assets/spider2.tscn +++ b/assets/spider2.tscn @@ -992,13 +992,13 @@ mesh = SubResource("ArrayMesh_3dwuk") visible = false mesh = SubResource("ArrayMesh_d210d") -[node name="Area3D" type="Area3D" parent="body" groups=["enemy_target"]] +[node name="backTarget" type="Area3D" parent="body" groups=["enemy_target"]] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.03709, 0) collision_layer = 128 collision_mask = 128 script = ExtResource("7_8vkma") -[node name="TargetShape" type="CollisionShape3D" parent="body/Area3D" groups=["enemy"]] +[node name="TargetShape" type="CollisionShape3D" parent="body/backTarget" groups=["enemy"]] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00258863, 1.30966, 0.442835) shape = SubResource("SphereShape3D_n7n6o") @@ -1037,8 +1037,8 @@ one_shot = true stream = ExtResource("10_2qmhc") volume_db = 10.0 -[connection signal="body_entered" from="body/Area3D" to="body/Area3D" method="_on_body_entered"] -[connection signal="body_part_hit" from="body/Area3D" to="." method="_on_area_3d_body_part_hit"] +[connection signal="body_entered" from="body/backTarget" to="body/backTarget" method="_on_body_entered"] +[connection signal="body_part_hit" from="body/backTarget" to="." method="_on_area_3d_body_part_hit"] [connection signal="timeout" from="Timers/prefire_timer" to="." method="_on_prefire_timer_timeout"] [connection signal="timeout" from="Timers/postfire_timer" to="." method="_on_postfire_timer_timeout"] [connection signal="timeout" from="Timers/knocked_timer" to="." method="_on_knocked_timer_timeout"] diff --git a/assets/texture_catcher.tscn b/assets/texture_catcher.tscn new file mode 100644 index 0000000..f0a321f --- /dev/null +++ b/assets/texture_catcher.tscn @@ -0,0 +1,87 @@ +[gd_scene load_steps=15 format=3 uid="uid://t0w0bolkucwl"] + +[ext_resource type="Script" path="res://scripts/texture_catcher.gd" id="1_x3mk2"] +[ext_resource type="PackedScene" uid="uid://2o2wcc5i1al4" path="res://assets/rocket_launcher.tscn" id="2_i6mk3"] +[ext_resource type="PackedScene" uid="uid://brl0bsqjl5dg3" path="res://assets/mac_10.tscn" id="2_u0ggi"] +[ext_resource type="PackedScene" uid="uid://cwutm86yp0rk6" path="res://assets/crown.tscn" id="3_gog5n"] +[ext_resource type="PackedScene" uid="uid://b5eclfg0cmmal" path="res://assets/revolver_1.tscn" id="3_yqo0y"] +[ext_resource type="PackedScene" uid="uid://dslxb3psx30vp" path="res://assets/pistol1.tscn" id="5_v3dls"] +[ext_resource type="PackedScene" uid="uid://dqwkal3t4gf2p" path="res://blunderbus.tscn" id="7_do5lr"] +[ext_resource type="PackedScene" uid="uid://djr7vnr1hcx82" path="res://assets/spider2.tscn" id="8_6tvxc"] +[ext_resource type="PackedScene" uid="uid://bcmd7elfjhppe" path="res://assets/tree_1.tscn" id="9_0lt7q"] +[ext_resource type="PackedScene" uid="uid://bycbdb5u5ewgl" path="res://assets/tree_2.tscn" id="10_g2f5o"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_n016m"] +sky_top_color = Color(1, 1, 1, 1) +sky_horizon_color = Color(0.81452, 0.81452, 0.81452, 1) +ground_bottom_color = Color(0.258082, 0.258082, 0.258082, 1) +ground_horizon_color = Color(0.81452, 0.81452, 0.81452, 1) + +[sub_resource type="Sky" id="Sky_qjshd"] +sky_material = SubResource("ProceduralSkyMaterial_n016m") + +[sub_resource type="Environment" id="Environment_w2vw8"] +background_mode = 2 +sky = SubResource("Sky_qjshd") +tonemap_mode = 2 +ssao_enabled = true +sdfgi_enabled = true +glow_enabled = true + +[sub_resource type="ViewportTexture" id="ViewportTexture_xiqw1"] +viewport_path = NodePath("CAPTURE/SubViewport") + +[node name="TextureCatcher" type="Node3D"] +script = ExtResource("1_x3mk2") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_w2vw8") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.736097, 0.553106, -0.390173, 0, 0.576432, 0.817145, 0.676876, 0.601498, -0.42431, 0, 0, 0) +shadow_enabled = true + +[node name="CAPTURE" type="Node3D" parent="."] + +[node name="SubViewport" type="SubViewport" parent="CAPTURE"] +transparent_bg = true +render_target_update_mode = 4 + +[node name="Camera3D" type="Camera3D" parent="CAPTURE/SubViewport"] +transform = Transform3D(-0.707107, 0, -0.707107, 0, 1, 0, 0.707107, 0, -0.707107, -0.697249, -2.38419e-07, -0.649448) + +[node name="snapshotModel" type="Node3D" parent="CAPTURE/SubViewport"] + +[node name="RocketLauncher" parent="CAPTURE/SubViewport/snapshotModel" instance=ExtResource("2_i6mk3")] +transform = Transform3D(0.992614, 0, 0.121315, 0, 1, 0, -0.121315, 0, 0.992614, 0.457345, -0.229299, 0.266961) + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = SubResource("ViewportTexture_xiqw1") + +[node name="PHOTOGRAPHED" type="Node3D" parent="."] +transform = Transform3D(-0.707107, 0, -0.707107, 0, 1, 0, 0.707107, 0, -0.707107, -0.697249, -2.38419e-07, -0.649448) +visible = false + +[node name="Crown" parent="PHOTOGRAPHED" instance=ExtResource("3_gog5n")] +transform = Transform3D(-0.896591, 0.345323, -0.277267, 0.104303, 0.773128, 0.625615, 0.430402, 0.532001, -0.729197, -0.297585, -0.374549, -1.68743) + +[node name="spider" parent="PHOTOGRAPHED" instance=ExtResource("8_6tvxc")] +transform = Transform3D(-0.707107, 0, 0.707107, 0, 1, 0, -0.707107, 0, -0.707107, -0.0527083, -0.717475, -2.38857) + +[node name="Tree1" parent="PHOTOGRAPHED" instance=ExtResource("9_0lt7q")] +transform = Transform3D(-0.292272, 0, 0.956335, 0, 1, 0, -0.956335, 0, -0.292272, -0.523788, -2.28829, -3.94497) + +[node name="Tree2" parent="PHOTOGRAPHED" instance=ExtResource("10_g2f5o")] +transform = Transform3D(0.576019, 0, -0.817437, 0, 1, 0, 0.817437, 0, 0.576019, -1.21889, -5.23911, -11.0324) + +[node name="mac10" parent="PHOTOGRAPHED" instance=ExtResource("2_u0ggi")] +transform = Transform3D(-0.707107, 0, 0.707107, 0, 1, 0, -0.707107, 0, -0.707107, -0.0338004, 0.0101067, -0.952258) + +[node name="revolver1" parent="PHOTOGRAPHED" instance=ExtResource("3_yqo0y")] +transform = Transform3D(-0.707107, 0, 0.707107, 0, 1, 0, -0.707107, 0, -0.707107, 0.116568, 0.0718296, -1.10969) + +[node name="Pistol" parent="PHOTOGRAPHED" instance=ExtResource("5_v3dls")] +transform = Transform3D(-0.707107, 0, 0.707107, 0, 1, 0, -0.707107, 0, -0.707107, 0.139735, -0.0145502, -1.10556) + +[node name="Blunderbus" parent="PHOTOGRAPHED" instance=ExtResource("7_do5lr")] +transform = Transform3D(-0.671708, 0, 0.740816, 0, 1, 0, -0.740816, 0, -0.671708, 0.160119, 2.38419e-07, -1.5088) diff --git a/assets/wea1AE4.tmp b/assets/wea1AE4.tmp new file mode 100644 index 0000000..b537c68 --- /dev/null +++ b/assets/wea1AE4.tmp @@ -0,0 +1,21 @@ +[gd_scene load_steps=2 format=3 uid="uid://dqgtnykkbngem"] + +[ext_resource type="Script" path="res://scripts/weapon_select.gd" id="1_qygnb"] + +[node name="WeaponSelect" type="Control"] +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -2.0 +offset_right = -2.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +script = ExtResource("1_qygnb") +outer_radius = 500 +inner_radius = 100 +line_width = 2 diff --git a/assets/weaD540.tmp b/assets/weaD540.tmp new file mode 100644 index 0000000..362e28c --- /dev/null +++ b/assets/weaD540.tmp @@ -0,0 +1,32 @@ +[gd_scene load_steps=8 format=3 uid="uid://dqgtnykkbngem"] + +[ext_resource type="Script" path="res://scripts/weapon_select.gd" id="1_qygnb"] +[ext_resource type="Texture2D" uid="uid://bho7c8s2yno12" path="res://assets/Textures/ObjectTextures/revolver1.png" id="2_wxfhl"] +[ext_resource type="Texture2D" uid="uid://gx3iw54iemho" path="res://assets/Textures/ObjectTextures/mac10.png" id="3_ofoph"] +[ext_resource type="Texture2D" uid="uid://dyvcljaoux8h" path="res://assets/Textures/ObjectTextures/RocketLauncher.png" id="5_72tmk"] +[ext_resource type="Texture2D" uid="uid://74id2drhfp2s" path="res://assets/Textures/ObjectTextures/Blunderbus.png" id="6_ows8e"] + +[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_uql6w"] +load_path = "res://.godot/imported/mac10.png-01420520bd1372fc6a82121c21a6d814.ctex" + +[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_jfua6"] +load_path = "res://.godot/imported/Pistol.png-088d61fee53cc956a8ad21cb8c0cb860.ctex" + +[node name="WeaponSelect" type="Control"] +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -2.0 +offset_right = -2.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +script = ExtResource("1_qygnb") +outer_radius = 500 +inner_radius = 100 +line_width = 2 +options = [ExtResource("3_ofoph"), ExtResource("2_wxfhl"), SubResource("CompressedTexture2D_uql6w"), SubResource("CompressedTexture2D_jfua6"), ExtResource("5_72tmk"), ExtResource("6_ows8e")] diff --git a/assets/weapon_select.tscn b/assets/weapon_select.tscn new file mode 100644 index 0000000..e260627 --- /dev/null +++ b/assets/weapon_select.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=2 format=3 uid="uid://dqgtnykkbngem"] + +[ext_resource type="Script" path="res://scripts/weapon_select.gd" id="1_qygnb"] + +[node name="WeaponSelect" type="Control"] +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -2.0 +offset_right = -2.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +script = ExtResource("1_qygnb") +outer_radius = 500 +inner_radius = 25 +line_width = 2 diff --git a/blunderbus.tscn b/blunderbus.tscn index d607307..9b86cb0 100644 --- a/blunderbus.tscn +++ b/blunderbus.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=45 format=4 uid="uid://dqwkal3t4gf2p"] +[gd_scene load_steps=46 format=4 uid="uid://dqwkal3t4gf2p"] [ext_resource type="Script" path="res://scripts/blunderbus.gd" id="1_w46uw"] [ext_resource type="PackedScene" uid="uid://717hhehp83k8" path="res://assets/shotgun_pellet.tscn" id="2_544x3"] +[ext_resource type="Texture2D" uid="uid://74id2drhfp2s" path="res://assets/Textures/ObjectTextures/Blunderbus.png" id="2_ejm2n"] [ext_resource type="Texture2D" uid="uid://dkn4i5834sc62" path="res://assets/Models/blunderbus.stock.albedo2.png" id="3_4fcbv"] [ext_resource type="Texture2D" uid="uid://cx4wjw3x8pa6q" path="res://assets/Models/blunderbus.metal.albedo.png" id="3_5l523"] [ext_resource type="Texture2D" uid="uid://cgpmyiyweyvl0" path="res://assets/Models/blunderbus.stock.normal2.png" id="4_3js22"] @@ -619,6 +620,7 @@ _data = { [node name="Blunderbus" type="Node3D" node_paths=PackedStringArray("anim_player", "barrel_raycast", "audio_fire", "audio_empty", "audio_reload")] script = ExtResource("1_w46uw") gun_name = "Blunderbuss" +gun_icon = ExtResource("2_ejm2n") fire_mode = 1 fov_zoom_amt = 0.998 recoil_amount = Vector3(0.5, 0.2, 0.2) diff --git a/gun_resource.tres b/gun_resource.tres new file mode 100644 index 0000000..cff9f76 --- /dev/null +++ b/gun_resource.tres @@ -0,0 +1,7 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://b6ilgwsha6j4e"] + +[ext_resource type="Texture2D" uid="uid://dlswdxm5aqfex" path="res://assets/Textures/ObjectTextures/revolver1.png" id="1_7ct5r"] + +[resource] +metadata/name = "Revolver" +metadata/texture = ExtResource("1_7ct5r") diff --git a/project.godot b/project.godot index c6b7b50..ceee5c4 100644 --- a/project.godot +++ b/project.godot @@ -35,7 +35,7 @@ version_control/autoload_on_startup=true [editor_plugins] -enabled=PackedStringArray("res://addons/proton_scatter/plugin.cfg") +enabled=PackedStringArray("res://addons/anthonyec.camera_preview/plugin.cfg", "res://addons/proton_scatter/plugin.cfg") [global_group] @@ -192,11 +192,6 @@ numb_9={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":57,"key_label":0,"unicode":57,"location":0,"echo":false,"script":null) ] } -numb_0={ -"deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":48,"key_label":0,"unicode":48,"location":0,"echo":false,"script":null) -] -} crouch={ "deadzone": 0.5, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) @@ -209,6 +204,12 @@ kill_self={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":75,"key_label":0,"unicode":107,"location":0,"echo":false,"script":null) ] } +weapon_select={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":3,"canceled":false,"pressed":false,"double_click":false,"script":null) +] +} [layer_names] diff --git a/scripts/EnemyTarget.gd b/scripts/EnemyTarget.gd index c1bb573..d4bc26e 100644 --- a/scripts/EnemyTarget.gd +++ b/scripts/EnemyTarget.gd @@ -1,6 +1,6 @@ extends Area3D -@export var damage :=1 +@export var damage : float = 1 var damage_number = preload("res://assets/damage_number.tscn") diff --git a/scripts/blunderbus.gd b/scripts/blunderbus.gd index a15bfc0..533a985 100644 --- a/scripts/blunderbus.gd +++ b/scripts/blunderbus.gd @@ -8,6 +8,7 @@ var cycle_count @export_group("Gun Feel") @export var gun_name : String +@export var gun_icon : Texture2D @export_enum("Auto", "Single", "Burst") var fire_mode: int @export var fov_zoom_amt = .98 @export var ads : bool = false diff --git a/scripts/gun.gd b/scripts/gun.gd index c68b33d..2ca4021 100644 --- a/scripts/gun.gd +++ b/scripts/gun.gd @@ -3,6 +3,7 @@ extends Node3D @export_group("Gun Feel") @export var gun_name : String +@export var gun_icon : Texture2D @export_enum("Auto", "Single", "Burst") var fire_mode: int @export var hitscan_enabled : bool = false @export var fov_zoom_amt = .98 diff --git a/scripts/player.gd b/scripts/player.gd index c65475b..1a2cf19 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -141,6 +141,7 @@ var controlled_elsewhere = false @onready var crouch_audio: AudioStreamPlayer3D = $Audio/Crouch @onready var hud: Control = $Head/Recoil/Camera3D/HUD @onready var clock_sound: AudioStreamPlayer = $Audio/ClockSound +@onready var weapon_select_menu: Control = $Head/Recoil/Camera3D/WeaponSelect func _ready(): @@ -383,7 +384,24 @@ func _physics_process(delta): for i in range(10): if Input.is_action_just_pressed("numb_" + str(i)): - weapon_select((i - 1)) + if gun != null: + if !gun.anim_player.is_playing(): + if i-1 != level_control.current_gun_index and i <= level_control.held_guns.size(): + weapon_select((i - 1)) + + if Input.is_action_just_pressed("weapon_select"): + weapon_select_menu.show() + Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED_HIDDEN) + controlled_elsewhere = true + gamespeed_controlled = true + Engine.time_scale = .01 + elif Input.is_action_just_released("weapon_select"): + var selection = weapon_select_menu.close() + if selection != null: + weapon_select(selection) + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + controlled_elsewhere = false + gamespeed_controlled = false #interact button if Input.is_action_just_pressed("interact"): @@ -539,13 +557,8 @@ func weapon_bob(vel : float, delta): weapon_holder.position.x = lerp(weapon_holder.position.x, def_weapon_holder_pos.x, .1 * delta) func weapon_select(gun_id): - if gun != null: - if !gun.anim_player.is_playing(): - if level_control.held_guns.size() >= (gun_id + 1) and level_control.current_gun_index != gun_id: - gun.anim_player.play("swap_out") - level_control.gun_spawn(gun_id) - else: - level_control.gun_spawn(gun_id) + gun.anim_player.play("swap_out") + level_control.gun_spawn(gun_id) func enemy_hit(): var hitmarker_spawn = hitmarker.instantiate() diff --git a/scripts/revolver_1.gd b/scripts/revolver_1.gd index 7b04f8f..74455dd 100644 --- a/scripts/revolver_1.gd +++ b/scripts/revolver_1.gd @@ -8,6 +8,7 @@ var cycle_count @export_group("Gun Feel") @export var gun_name : String +@export var gun_icon : Texture2D @export_enum("Auto", "Single", "Burst") var fire_mode: int @export var fov_zoom_amt = .98 @export var ads : bool = false diff --git a/scripts/rocket_launcher.gd b/scripts/rocket_launcher.gd index b748cdd..73cad5b 100644 --- a/scripts/rocket_launcher.gd +++ b/scripts/rocket_launcher.gd @@ -9,6 +9,7 @@ var ads = false @export_group("Gun Feel") @export var gun_name : String +@export var gun_icon : Texture2D @export_enum("Auto", "Single", "Burst") var fire_mode: int @export var fov_zoom_amt = .98 @export var recoil_amount : Vector3 = Vector3(.2,0,0) diff --git a/scripts/signal_bus.gd b/scripts/signal_bus.gd index e9de7dd..1cf2de1 100644 --- a/scripts/signal_bus.gd +++ b/scripts/signal_bus.gd @@ -8,3 +8,4 @@ signal king_killed() signal enemy_count_changed() signal game_loaded() signal player_hit() +signal weapon_list_changed() diff --git a/scripts/texture_catcher.gd b/scripts/texture_catcher.gd new file mode 100644 index 0000000..b5bf03a --- /dev/null +++ b/scripts/texture_catcher.gd @@ -0,0 +1,22 @@ +@tool +extends Node3D + +@onready var sub_viewport: SubViewport = $CAPTURE/SubViewport +@onready var snapshot_model: Node3D = $CAPTURE/SubViewport/snapshotModel + +@export var take_snapshot : bool = false + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + if take_snapshot: + var snapshot_name = snapshot_model.get_child(0).get_name() + await get_tree().create_timer(.5).timeout + var img = sub_viewport.get_viewport().get_texture().get_image() + var image_path = "assets/Textures/ObjectTextures/%s.png" % snapshot_name + img.save_png(image_path) + take_snapshot = false diff --git a/scripts/trackerGun.gd b/scripts/trackerGun.gd index f1e6581..04d6376 100644 --- a/scripts/trackerGun.gd +++ b/scripts/trackerGun.gd @@ -3,6 +3,7 @@ extends Node3D @export_group("Gun Feel") @export var gun_name : String +@export var gun_icon : Texture2D @export_enum("Auto", "Single", "Burst") var fire_mode: int @export var hitscan_enabled : bool = false @export var ads : bool = false diff --git a/scripts/weapon_pickup.gd b/scripts/weapon_pickup.gd index 1ebc78d..93ab988 100644 --- a/scripts/weapon_pickup.gd +++ b/scripts/weapon_pickup.gd @@ -32,6 +32,7 @@ func picked_up(): if level_control.player.gun != null: level_control.player.gun.anim_player.play("swap_out") level_control.gun_spawn(weapon_id) + SignalBus.emit_signal("weapon_list_changed") queue_free() func save(): diff --git a/scripts/weapon_select.gd b/scripts/weapon_select.gd new file mode 100644 index 0000000..42ff4d3 --- /dev/null +++ b/scripts/weapon_select.gd @@ -0,0 +1,103 @@ +#@tool +extends Control + +@export var outer_radius : int = 256 +@export var inner_radius : int = 256 +@export var line_width : int = 4 + +var options = [] + +@onready var level_control = get_tree().current_scene + +const bkg_color : Color = Color(1, 1, 1, .5) +const line_color : Color = Color(1,1,1) +const select_color = Color(1, 1, 1, .5) +const IMAGE_SIZE = Vector2(512,512) + + +var selection + +func close(): + hide() + return selection + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + update_weapon_list() + SignalBus.weapon_list_changed.connect(update_weapon_list) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + + var mouse_pos = get_local_mouse_position() + var mouse_radius = mouse_pos.length() + + if mouse_radius < inner_radius: + selection = null + else: + var mouse_rads = fposmod(mouse_pos.angle() * -1, TAU) + selection = ceil((mouse_rads / TAU) * (len(options)+1)) + + + + queue_redraw() + +func _draw(): + var offset = IMAGE_SIZE/ -2 + + if selection == null: + draw_circle(Vector2.ZERO,inner_radius,select_color) + + + draw_circle(Vector2.ZERO, outer_radius, bkg_color) + draw_arc(Vector2.ZERO,inner_radius,0, TAU, 128,line_color,line_width,true) + + if len(options) >= 1: + + # draw separator lines + for i in range(len(options)): + var rads = TAU * i / (len(options)) + var point = Vector2.from_angle(rads) + draw_line( + point * inner_radius, + point * outer_radius, + line_color, + line_width, + true + ) + + for i in range(0,len(options)): + var start_rads = (TAU * (i-1)) / (len(options)) + var end_rads = (TAU * i) / (len(options)) + var mid_rads = (start_rads + end_rads)/2.0 * -1 + var radius_mid = (inner_radius + outer_radius) / 2 + + var draw_pos = radius_mid * Vector2.from_angle(mid_rads) + offset + + var object = options[i].instantiate() + var texture = object.gun_icon + + if selection == i: + var points_per_arc = 32 + var points_inner = PackedVector2Array() + var points_outer = PackedVector2Array() + + for j in range(points_per_arc + 1): + var angle = start_rads + j * (end_rads - start_rads) / points_per_arc + points_inner.append(inner_radius * Vector2.from_angle(TAU-angle)) + points_outer.append(outer_radius * Vector2.from_angle(TAU-angle)) + + points_outer.reverse() + draw_polygon( + points_inner + points_outer, + PackedColorArray([select_color]) + ) + + draw_texture( + texture, + Vector2(draw_pos) + ) + +func update_weapon_list(): + options = level_control.held_guns