organize scripts; wip ui overhaul
This commit is contained in:
parent
89bcba0ff2
commit
ed1a2ca7e3
97 changed files with 717 additions and 397 deletions
|
@ -2,3 +2,11 @@ root = true
|
|||
|
||||
[*]
|
||||
charset = utf-8
|
||||
|
||||
[*.gd]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ func _init(start: int, end: int, inclusive: bool = false) -> void:
|
|||
self.inclusive = inclusive
|
||||
|
||||
static func from_sized(value: Variant) -> Result:
|
||||
match KCUtils.get_size(value):
|
||||
match K.get_size(value):
|
||||
var len when len.is_ok():
|
||||
return Result.ok(IntRange.new(0, len.unwrap()))
|
||||
var e: return e
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class_name KCUtils
|
||||
class_name K
|
||||
|
||||
static func remove_children(node: Node, delete: bool = true):
|
||||
for i in range(node.get_child_count() - 1, -1, -1):
|
||||
|
@ -15,6 +15,10 @@ static func get_class_name(value: Object) -> String:
|
|||
_: return script.get_instance_base_type()
|
||||
_: return value.get_class()
|
||||
|
||||
static func is_array_like(value: Variant) -> bool:
|
||||
var type = typeof(value)
|
||||
return type >= 28 and type <= 38 or type == TYPE_STRING or type == TYPE_STRING_NAME
|
||||
|
||||
static func is_string_like(value: Variant) -> bool:
|
||||
match typeof(value):
|
||||
TYPE_STRING: return true
|
||||
|
@ -79,3 +83,9 @@ static func get_size(value: Variant) -> Result:
|
|||
|
||||
static func len(value: Variant) -> int:
|
||||
return get_size(value).unwrap()
|
||||
|
||||
static func iter(value: Variant) -> Iterator:
|
||||
if is_array_like(value): return ListIterator.from_array(value)
|
||||
if typeof(value) == TYPE_OBJECT: return VariantIterator.new(value)
|
||||
if typeof(value) == TYPE_DICTIONARY: return DictionaryIterator.new(value)
|
||||
return SingletonIterator.new(value)
|
||||
|
|
7
godot/assets/icons/10mm_icon.tres
Normal file
7
godot/assets/icons/10mm_icon.tres
Normal file
|
@ -0,0 +1,7 @@
|
|||
[gd_resource type="AtlasTexture" load_steps=2 format=3 uid="uid://csnm0disev20f"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://d3ergv453flsw" path="res://assets/sprites.png" id="1_nybgi"]
|
||||
|
||||
[resource]
|
||||
atlas = ExtResource("1_nybgi")
|
||||
region = Rect2(72, 272, 48, 32)
|
|
@ -4,5 +4,4 @@
|
|||
|
||||
[resource]
|
||||
atlas = ExtResource("1_gm5ao")
|
||||
region = Rect2(256, 128, 64, 64)
|
||||
margin = Rect2(-10, -12, -20, -20)
|
||||
region = Rect2(275, 142, 25, 39)
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
|
||||
[resource]
|
||||
atlas = ExtResource("1_y5otb")
|
||||
region = Rect2(192, 256, 64, 64)
|
||||
margin = Rect2(0, -10, 0, -12)
|
||||
region = Rect2(193, 272, 62, 40)
|
||||
|
|
12
godot/resources/items/9mm_ammo.tres
Normal file
12
godot/resources/items/9mm_ammo.tres
Normal file
|
@ -0,0 +1,12 @@
|
|||
[gd_resource type="Resource" script_class="Item" load_steps=3 format=3 uid="uid://ud2qc6eul8lt"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d1imxjix6ljul" path="res://src/attributes/attribute.gd" id="1_gkq1r"]
|
||||
[ext_resource type="Script" uid="uid://bqprls343ue6e" path="res://src/items/item.gd" id="2_4ckx0"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_4ckx0")
|
||||
name = "9mm Ammo"
|
||||
description = ""
|
||||
max_stack = 99
|
||||
attributes = Array[ExtResource("1_gkq1r")]([])
|
||||
metadata/_custom_type_script = "uid://bqprls343ue6e"
|
|
@ -1,12 +1,14 @@
|
|||
[gd_resource type="Resource" script_class="Item" load_steps=3 format=3 uid="uid://cqfnwpmo4fyv4"]
|
||||
[gd_resource type="Resource" script_class="Item" load_steps=4 format=3 uid="uid://cqfnwpmo4fyv4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bqprls343ue6e" path="res://src/item.gd" id="1_7ur50"]
|
||||
[ext_resource type="Script" uid="uid://d1imxjix6ljul" path="res://src/attributes/attribute.gd" id="1_nv3up"]
|
||||
[ext_resource type="Texture2D" uid="uid://dngw0c0dc6u7x" path="res://assets/icons/key_icon.tres" id="1_ykwyx"]
|
||||
[ext_resource type="Script" uid="uid://bqprls343ue6e" path="res://src/items/item.gd" id="3_4rdgs"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_7ur50")
|
||||
script = ExtResource("3_4rdgs")
|
||||
name = "Debug Key"
|
||||
description = "An unusual key card."
|
||||
max_stack = 1
|
||||
icon = ExtResource("1_ykwyx")
|
||||
attributes = Array[ExtResource("1_nv3up")]([])
|
||||
metadata/_custom_type_script = "uid://bqprls343ue6e"
|
||||
|
|
|
@ -1,16 +1,32 @@
|
|||
[gd_resource type="Resource" script_class="EquippableItem" load_steps=5 format=3 uid="uid://crgwey6ibaf2h"]
|
||||
[gd_resource type="Resource" script_class="EquippableItem" load_steps=10 format=3 uid="uid://crgwey6ibaf2h"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://isqkayrtr7t8" path="res://scenes/pistol.tscn" id="1_6ttue"]
|
||||
[ext_resource type="Script" uid="uid://d1imxjix6ljul" path="res://src/attributes/attribute.gd" id="1_7dru5"]
|
||||
[ext_resource type="Texture2D" uid="uid://dvxrifa0iu8ql" path="res://assets/icons/pistol_icon.tres" id="1_112eb"]
|
||||
[ext_resource type="PackedScene" uid="uid://dfljhd4e3l6j2" path="res://scenes/pistol_preview.tscn" id="1_gintf"]
|
||||
[ext_resource type="Script" uid="uid://c710qg683rqbc" path="res://src/equippable_item.gd" id="1_lqglu"]
|
||||
[ext_resource type="Script" uid="uid://c710qg683rqbc" path="res://src/items/equippable_item.gd" id="1_lqglu"]
|
||||
[ext_resource type="Script" uid="uid://bbigpwchxitb5" path="res://src/attributes/ammo_attribute.gd" id="2_j7ges"]
|
||||
[ext_resource type="Script" uid="uid://c1y3loxtmkeg3" path="res://src/attributes/equippable_attribute.gd" id="3_fcfbw"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_6opap"]
|
||||
script = ExtResource("2_j7ges")
|
||||
max_capacity = 10
|
||||
metadata/_custom_type_script = "uid://bbigpwchxitb5"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_moakd"]
|
||||
script = ExtResource("3_fcfbw")
|
||||
type = 0
|
||||
metadata/_custom_type_script = "uid://c1y3loxtmkeg3"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_lqglu")
|
||||
type = 0
|
||||
ammo_capacity = 0
|
||||
name = "Pistol"
|
||||
description = "A semi-automatic pistol. Fires 10mm ammunition from a 10-round magazine. Easy to use, high rate of fire."
|
||||
max_stack = 1
|
||||
icon = ExtResource("1_112eb")
|
||||
scene = ExtResource("1_6ttue")
|
||||
preview_scene = ExtResource("1_gintf")
|
||||
attributes = Array[ExtResource("1_7dru5")]([SubResource("Resource_6opap"), SubResource("Resource_moakd")])
|
||||
metadata/_custom_type_script = "uid://c710qg683rqbc"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[gd_resource type="Resource" script_class="Inventory" load_steps=5 format=3 uid="uid://bllq6ri54q3ne"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://1rjq1ttxq4nd" path="res://src/item_instance.gd" id="1_uptie"]
|
||||
[ext_resource type="Script" uid="uid://dh4ytedxidq0x" path="res://src/inventory.gd" id="2_1njko"]
|
||||
[ext_resource type="Script" uid="uid://1rjq1ttxq4nd" path="res://src/items/item_instance.gd" id="1_uptie"]
|
||||
[ext_resource type="Script" uid="uid://dh4ytedxidq0x" path="res://src/items/inventory.gd" id="2_1njko"]
|
||||
[ext_resource type="Resource" uid="uid://cqfnwpmo4fyv4" path="res://resources/items/key.tres" id="2_85a8j"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_hfe8y"]
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
[gd_resource type="Theme" load_steps=6 format=3 uid="uid://bb6tvyqikcf3r"]
|
||||
[gd_resource type="Theme" load_steps=3 format=3 uid="uid://bb6tvyqikcf3r"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_odwru"]
|
||||
bg_color = Color(0.6, 0.6, 0.6, 0)
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_t6lws"]
|
||||
bg_color = Color(0.92549, 0.243137, 0.0392157, 1)
|
||||
|
||||
[sub_resource type="SystemFont" id="SystemFont_t6lws"]
|
||||
font_names = PackedStringArray("Monospace")
|
||||
font_weight = 600
|
||||
keep_rounding_remainders = false
|
||||
multichannel_signed_distance_field = true
|
||||
|
||||
[sub_resource type="SystemFont" id="SystemFont_odwru"]
|
||||
font_names = PackedStringArray("monospace")
|
||||
font_weight = 500
|
||||
multichannel_signed_distance_field = true
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_4gq11"]
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nj55m"]
|
||||
bg_color = Color(0.6, 0.6, 0.6, 0)
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
|
@ -26,20 +12,8 @@ border_width_bottom = 1
|
|||
border_color = Color(0.92549, 0.243137, 0.0392157, 1)
|
||||
|
||||
[resource]
|
||||
BoxContent/base_type = &"Panel"
|
||||
BoxContent/styles/panel = SubResource("StyleBoxFlat_odwru")
|
||||
BoxHeader/base_type = &"PanelContainer"
|
||||
BoxHeader/styles/panel = SubResource("StyleBoxFlat_t6lws")
|
||||
BoxHeaderLabel/base_type = &"Label"
|
||||
BoxHeaderLabel/colors/font_color = Color(0, 0, 0, 1)
|
||||
BoxHeaderLabel/font_sizes/font_size = 8
|
||||
BoxHeaderLabel/fonts/font = SubResource("SystemFont_t6lws")
|
||||
HBoxContainer/constants/separation = 8
|
||||
Label/font_sizes/font_size = 12
|
||||
Label/fonts/font = SubResource("SystemFont_odwru")
|
||||
MarginContainer/constants/margin_bottom = 4
|
||||
MarginContainer/constants/margin_left = 4
|
||||
MarginContainer/constants/margin_right = 4
|
||||
MarginContainer/constants/margin_top = 4
|
||||
PanelContainer/styles/panel = SubResource("StyleBoxFlat_4gq11")
|
||||
RichTextLabel/colors/default_color = Color(0.0745098, 0.0745098, 0.0745098, 1)
|
||||
BoxTitle/base_type = &"PanelContainer"
|
||||
BoxTitle/styles/panel = SubResource("StyleBoxFlat_odwru")
|
||||
BoxTitleText/base_type = &"Label"
|
||||
BoxTitleText/colors/font_color = Color(0.0745098, 0.0745098, 0.0745098, 1)
|
||||
PanelContainer/styles/panel = SubResource("StyleBoxFlat_nj55m")
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cidwsnulug6fl"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cidwsnulug6fl"]
|
||||
|
||||
[ext_resource type="Theme" uid="uid://bb6tvyqikcf3r" path="res://scenes/box_ui.tres" id="1_e1aew"]
|
||||
[ext_resource type="Script" uid="uid://bnumwlio6adb8" path="res://src/ui/box.gd" id="2_jp73w"]
|
||||
|
||||
[node name="Box" type="PanelContainer"]
|
||||
[node name="Box" type="PanelContainer" node_paths=PackedStringArray("title_label", "body_container")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme = ExtResource("1_e1aew")
|
||||
script = ExtResource("2_jp73w")
|
||||
title_label = NodePath("Container/Header/TitleContainer/Label")
|
||||
body_container = NodePath("Container/Content")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
[node name="Container" type="VBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Header" type="PanelContainer" parent="VBoxContainer"]
|
||||
[node name="Header" type="PanelContainer" parent="Container"]
|
||||
layout_mode = 2
|
||||
theme = ExtResource("1_e1aew")
|
||||
theme_type_variation = &"BoxHeader"
|
||||
theme_type_variation = &"BoxTitle"
|
||||
|
||||
[node name="TitleContainer" type="MarginContainer" parent="VBoxContainer/Header"]
|
||||
[node name="TitleContainer" type="MarginContainer" parent="Container/Header"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Body" type="PanelContainer" parent="VBoxContainer"]
|
||||
[node name="Label" type="Label" parent="Container/Header/TitleContainer"]
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"BoxTitleText"
|
||||
|
||||
[node name="Content" type="PanelContainer" parent="Container"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme = ExtResource("1_e1aew")
|
||||
|
|
9
godot/scenes/context_menu.tscn
Normal file
9
godot/scenes/context_menu.tscn
Normal file
|
@ -0,0 +1,9 @@
|
|||
[gd_scene format=3 uid="uid://bgn32l1f007w2"]
|
||||
|
||||
[node name="ContextMenu" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
|
@ -1,15 +1,13 @@
|
|||
[gd_scene load_steps=14 format=3 uid="uid://cn7tgd4y67wnd"]
|
||||
[gd_scene load_steps=12 format=3 uid="uid://cn7tgd4y67wnd"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://qvoqvonnxwfc" path="res://src/inventory_ui.gd" id="1_a0rpf"]
|
||||
[ext_resource type="Script" uid="uid://bx4wxlm5mv268" path="res://src/root_control.gd" id="1_as33y"]
|
||||
[ext_resource type="Theme" uid="uid://bb6tvyqikcf3r" path="res://scenes/box_ui.tres" id="1_sr8g6"]
|
||||
[ext_resource type="Resource" uid="uid://bllq6ri54q3ne" path="res://resources/player_inventory.tres" id="2_as33y"]
|
||||
[ext_resource type="Script" uid="uid://b7j7weoa8tikm" path="res://src/ui/inventory_screen.gd" id="2_g71ie"]
|
||||
[ext_resource type="PackedScene" uid="uid://gn8k2ir47n1m" path="res://scenes/inventory_item.tscn" id="3_tg4gd"]
|
||||
[ext_resource type="Script" uid="uid://bpwbaanf6w65h" path="res://src/index_carousel.gd" id="5_uae8j"]
|
||||
[ext_resource type="Script" uid="uid://c8m7eq6a3tpgu" path="res://src/item_details_ui.gd" id="6_s887n"]
|
||||
[ext_resource type="Script" uid="uid://c8m7eq6a3tpgu" path="res://src/ui/item_detail_ui.gd" id="4_yyk2a"]
|
||||
[ext_resource type="Script" uid="uid://bpwbaanf6w65h" path="res://src/ui/index_carousel.gd" id="5_uae8j"]
|
||||
[ext_resource type="Resource" uid="uid://cxm3s081hnw8l" path="res://resources/player_equipment.tres" id="7_s887n"]
|
||||
[ext_resource type="PackedScene" uid="uid://cidwsnulug6fl" path="res://scenes/box_ui.tscn" id="8_g71ie"]
|
||||
[ext_resource type="Script" uid="uid://c4gfdpuc14mpq" path="res://src/cancel_button.gd" id="10_p7iul"]
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_as33y"]
|
||||
size = Vector2(128, 128)
|
||||
|
@ -20,20 +18,25 @@ size = Vector2(128, 128)
|
|||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_usnyx"]
|
||||
size = Vector2(128, 64)
|
||||
|
||||
[node name="Inventory" type="Control"]
|
||||
[node name="Inventory" type="Control" node_paths=PackedStringArray("carousel", "item_details")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 2.0
|
||||
offset_right = 2.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
focus_mode = 2
|
||||
theme = ExtResource("1_sr8g6")
|
||||
script = ExtResource("1_as33y")
|
||||
open_action = &"open_inventory"
|
||||
close_action = &"ui_close_inventory"
|
||||
script = ExtResource("2_g71ie")
|
||||
inventory = ExtResource("2_as33y")
|
||||
equipment = ExtResource("7_s887n")
|
||||
inventory_item_scene = ExtResource("3_tg4gd")
|
||||
carousel = NodePath("MarginContainer/Contents/MarginContainer/Carousel")
|
||||
item_details = NodePath("MarginContainer/Contents/Details")
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
|
@ -59,25 +62,9 @@ alignment = 1
|
|||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/Contents"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="InventoryList" type="Control" parent="MarginContainer/Contents/MarginContainer" node_paths=PackedStringArray("carousel")]
|
||||
custom_minimum_size = Vector2(0, 150)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource("1_a0rpf")
|
||||
inventory = ExtResource("2_as33y")
|
||||
item_scene = ExtResource("3_tg4gd")
|
||||
carousel = NodePath("Carousel")
|
||||
metadata/_custom_type_script = "uid://qvoqvonnxwfc"
|
||||
|
||||
[node name="Carousel" type="Container" parent="MarginContainer/Contents/MarginContainer/InventoryList"]
|
||||
[node name="Carousel" type="Container" parent="MarginContainer/Contents/MarginContainer"]
|
||||
custom_minimum_size = Vector2(0, 100)
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
scale = Vector2(1, 1.01)
|
||||
layout_mode = 2
|
||||
script = ExtResource("5_uae8j")
|
||||
with_drag = true
|
||||
with_clamp = true
|
||||
|
@ -85,39 +72,39 @@ item_size = Vector2(150, 100)
|
|||
item_seperation = 64
|
||||
snap_behavior = 2
|
||||
paging_requirement = 100
|
||||
manual_carousel_duration = 0.2
|
||||
metadata/_custom_type_script = "uid://bpwbaanf6w65h"
|
||||
|
||||
[node name="Details" type="HBoxContainer" parent="MarginContainer/Contents" node_paths=PackedStringArray("viewport", "description_label", "action_menu")]
|
||||
[node name="Details" type="HBoxContainer" parent="MarginContainer/Contents" node_paths=PackedStringArray("viewport", "description_label")]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource("6_s887n")
|
||||
equipment = ExtResource("7_s887n")
|
||||
viewport = NodePath("ItemDisplay/VBoxContainer/Body/Display/SubViewport")
|
||||
description_label = NodePath("ItemDescription/VBoxContainer/Body/MarginContainer/Label")
|
||||
action_menu = NodePath("ItemDescription/VBoxContainer/Body/MarginContainer/Box")
|
||||
script = ExtResource("4_yyk2a")
|
||||
viewport = NodePath("ItemDisplay/Container/Content/SubViewport")
|
||||
description_label = NodePath("ItemDescription/Container/Header/TitleContainer/Label")
|
||||
|
||||
[node name="PlayerDetails" parent="MarginContainer/Contents/Details" instance=ExtResource("8_g71ie")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Body" parent="MarginContainer/Contents/Details/PlayerDetails/VBoxContainer" index="1"]
|
||||
clip_contents = true
|
||||
|
||||
[node name="PlayerInfo" type="VBoxContainer" parent="MarginContainer/Contents/Details/PlayerDetails/VBoxContainer/Body" index="0"]
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/Contents/Details/PlayerDetails/Container/Content" index="0"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/margin_left = 24
|
||||
theme_override_constants/margin_right = 24
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/Contents/Details/PlayerDetails/VBoxContainer/Body/PlayerInfo"]
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/Contents/Details/PlayerDetails/Container/Content/MarginContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/Contents/Details/PlayerDetails/Container/Content/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
texture = SubResource("PlaceholderTexture2D_as33y")
|
||||
|
||||
[node name="TextureRect2" type="TextureRect" parent="MarginContainer/Contents/Details/PlayerDetails/VBoxContainer/Body/PlayerInfo"]
|
||||
[node name="TextureRect2" type="TextureRect" parent="MarginContainer/Contents/Details/PlayerDetails/Container/Content/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
texture = SubResource("PlaceholderTexture2D_tg4gd")
|
||||
|
||||
[node name="TextureRect3" type="TextureRect" parent="MarginContainer/Contents/Details/PlayerDetails/VBoxContainer/Body/PlayerInfo"]
|
||||
[node name="TextureRect3" type="TextureRect" parent="MarginContainer/Contents/Details/PlayerDetails/Container/Content/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
texture = SubResource("PlaceholderTexture2D_usnyx")
|
||||
|
@ -127,124 +114,44 @@ layout_mode = 2
|
|||
size_flags_horizontal = 3
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="Display" type="SubViewportContainer" parent="MarginContainer/Contents/Details/ItemDisplay/VBoxContainer/Body" index="0"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
stretch = true
|
||||
[node name="Camera3D" type="Camera3D" parent="MarginContainer/Contents/Details/ItemDisplay/Container/Content" index="0"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2)
|
||||
|
||||
[node name="SubViewport" type="SubViewport" parent="MarginContainer/Contents/Details/ItemDisplay/VBoxContainer/Body/Display"]
|
||||
[node name="SubViewport" type="SubViewport" parent="MarginContainer/Contents/Details/ItemDisplay/Container/Content" index="1"]
|
||||
own_world_3d = true
|
||||
transparent_bg = true
|
||||
handle_input_locally = false
|
||||
size = Vector2i(374, 464)
|
||||
size = Vector2i(374, 514)
|
||||
render_target_update_mode = 4
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="MarginContainer/Contents/Details/ItemDisplay/VBoxContainer/Body/Display/SubViewport"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2)
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="MarginContainer/Contents/Details/ItemDisplay/VBoxContainer/Body/Display/SubViewport"]
|
||||
transform = Transform3D(0.71887, 0.431921, -0.544674, -0.0668683, 0.822874, 0.564277, 0.691921, -0.36922, 0.620421, 0, 0, 0)
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="MarginContainer/Contents/Details/ItemDisplay/Container/Content" index="2"]
|
||||
transform = Transform3D(0.71887, 0.431921, -0.544675, -0.0668683, 0.822874, 0.564276, 0.691921, -0.36922, 0.620421, 0, 0, 0)
|
||||
|
||||
[node name="ItemDescription" parent="MarginContainer/Contents/Details" instance=ExtResource("8_g71ie")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 2
|
||||
|
||||
[node name="VBoxContainer" parent="MarginContainer/Contents/Details/ItemDescription" index="0"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Header" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer" index="0"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="TitleContainer" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Header" index="0"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Body" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer" index="1"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body" index="0"]
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/Contents/Details/ItemDescription/Container/Content" index="0"]
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer"]
|
||||
[node name="Label" type="Label" parent="MarginContainer/Contents/Details/ItemDescription/Container/Content/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 1
|
||||
size_flags_vertical = 3
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="Box" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer" instance=ExtResource("8_g71ie")]
|
||||
[node name="ContextMenu" parent="MarginContainer/Contents/Details/ItemDescription/Container/Content/MarginContainer" instance=ExtResource("8_g71ie")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 8
|
||||
focus_mode = 2
|
||||
|
||||
[node name="VBoxContainer" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box" index="0"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Header" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer" index="0"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="TitleContainer" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Header" index="0"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Body" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer" index="1"]
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body" index="0"]
|
||||
[node name="Label" type="Label" parent="MarginContainer/Contents/Details/ItemDescription/Container/Content/MarginContainer/ContextMenu/Container/Content" index="0"]
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="UseButton" type="Button" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_left = NodePath(".")
|
||||
focus_neighbor_top = NodePath(".")
|
||||
focus_neighbor_right = NodePath(".")
|
||||
focus_neighbor_bottom = NodePath("../CombineButton")
|
||||
focus_next = NodePath("../CombineButton")
|
||||
focus_previous = NodePath(".")
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 2
|
||||
text = "USE"
|
||||
alignment = 0
|
||||
script = ExtResource("10_p7iul")
|
||||
metadata/_custom_type_script = "uid://c4gfdpuc14mpq"
|
||||
|
||||
[node name="CombineButton" type="Button" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_left = NodePath(".")
|
||||
focus_neighbor_top = NodePath("../UseButton")
|
||||
focus_neighbor_right = NodePath(".")
|
||||
focus_neighbor_bottom = NodePath("../InspectButton")
|
||||
focus_next = NodePath("../InspectButton")
|
||||
focus_previous = NodePath("../UseButton")
|
||||
mouse_filter = 1
|
||||
text = "COMBINE"
|
||||
alignment = 0
|
||||
script = ExtResource("10_p7iul")
|
||||
metadata/_custom_type_script = "uid://c4gfdpuc14mpq"
|
||||
|
||||
[node name="InspectButton" type="Button" parent="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_left = NodePath(".")
|
||||
focus_neighbor_top = NodePath("../CombineButton")
|
||||
focus_neighbor_right = NodePath(".")
|
||||
focus_neighbor_bottom = NodePath(".")
|
||||
focus_next = NodePath(".")
|
||||
focus_previous = NodePath("../CombineButton")
|
||||
mouse_filter = 1
|
||||
text = "INSPECT"
|
||||
alignment = 0
|
||||
script = ExtResource("10_p7iul")
|
||||
metadata/_custom_type_script = "uid://c4gfdpuc14mpq"
|
||||
|
||||
[connection signal="item_focused" from="MarginContainer/Contents/MarginContainer/InventoryList" to="MarginContainer/Contents/Details" method="_on_updated"]
|
||||
[connection signal="item_selected" from="MarginContainer/Contents/MarginContainer/InventoryList" to="MarginContainer/Contents/Details" method="_on_selected"]
|
||||
[connection signal="hidden" from="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box" to="." method="grab_focus"]
|
||||
[connection signal="visibility_changed" from="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box" to="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer/UseButton" method="grab_focus"]
|
||||
[connection signal="pressed" from="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer/UseButton" to="MarginContainer/Contents/Details" method="use"]
|
||||
[connection signal="pressed" from="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer/CombineButton" to="MarginContainer/Contents/Details" method="combine"]
|
||||
[connection signal="pressed" from="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box/VBoxContainer/Body/VBoxContainer/InspectButton" to="MarginContainer/Contents/Details" method="inspect"]
|
||||
|
||||
[editable path="MarginContainer/Contents/Details/PlayerDetails"]
|
||||
[editable path="MarginContainer/Contents/Details/ItemDisplay"]
|
||||
[editable path="MarginContainer/Contents/Details/ItemDescription"]
|
||||
[editable path="MarginContainer/Contents/Details/ItemDescription/VBoxContainer/Body/MarginContainer/Box"]
|
||||
[editable path="MarginContainer/Contents/Details/ItemDescription/Container/Content/MarginContainer/ContextMenu"]
|
||||
|
|
|
@ -1,23 +1,14 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://gn8k2ir47n1m"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://gn8k2ir47n1m"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dt67n4jti376d" path="res://src/item_ui.gd" id="1_letey"]
|
||||
[ext_resource type="Script" uid="uid://c2yaayl4msnf1" path="res://src/ui/item_ui.gd" id="1_letey"]
|
||||
[ext_resource type="PackedScene" uid="uid://cidwsnulug6fl" path="res://scenes/box_ui.tscn" id="1_y87vu"]
|
||||
[ext_resource type="Theme" uid="uid://bb6tvyqikcf3r" path="res://scenes/box_ui.tres" id="3_y87vu"]
|
||||
|
||||
[node name="Item" node_paths=PackedStringArray("name_label", "icon_texture") instance=ExtResource("1_y87vu")]
|
||||
[node name="Item" node_paths=PackedStringArray("_title_label", "_icon_texture") instance=ExtResource("1_y87vu")]
|
||||
script = ExtResource("1_letey")
|
||||
name_label = NodePath("VBoxContainer/Header/TitleContainer/Label")
|
||||
icon_texture = NodePath("VBoxContainer/Body/TextureRect")
|
||||
_title_label = NodePath("Container/Header/TitleContainer/Label")
|
||||
_icon_texture = NodePath("Container/Content/TextureRect")
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer/Header/TitleContainer" index="0"]
|
||||
layout_mode = 2
|
||||
theme = ExtResource("3_y87vu")
|
||||
theme_type_variation = &"BoxHeaderLabel"
|
||||
text = "pistol"
|
||||
vertical_alignment = 1
|
||||
uppercase = true
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="VBoxContainer/Body" index="0"]
|
||||
[node name="TextureRect" type="TextureRect" parent="Container/Content" index="0"]
|
||||
layout_mode = 2
|
||||
expand_mode = 3
|
||||
stretch_mode = 5
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
[gd_scene load_steps=17 format=3 uid="uid://dttyp3682enn7"]
|
||||
[gd_scene load_steps=19 format=3 uid="uid://dttyp3682enn7"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://crbrniwi6kd3p" path="res://scenes/player.tscn" id="1_2q6dc"]
|
||||
[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_klq6b"]
|
||||
[ext_resource type="Script" uid="uid://ds8lef4lc6xuj" path="res://src/door.gd" id="2_w8frs"]
|
||||
[ext_resource type="Script" uid="uid://ds8lef4lc6xuj" path="res://src/world/door.gd" id="2_w8frs"]
|
||||
[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_b121j"]
|
||||
[ext_resource type="Script" uid="uid://dyghf5fq7s72x" path="res://src/interactable.gd" id="3_w8frs"]
|
||||
[ext_resource type="Script" uid="uid://dyghf5fq7s72x" path="res://src/world/interactable.gd" id="3_w8frs"]
|
||||
[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_8c41q"]
|
||||
[ext_resource type="Script" uid="uid://pdpejp2xor23" path="res://src/persistence.gd" id="4_mx8sn"]
|
||||
[ext_resource type="Resource" uid="uid://cqfnwpmo4fyv4" path="res://resources/items/key.tres" id="7_8c41q"]
|
||||
[ext_resource type="Script" uid="uid://35hnuxagjlo2" path="res://src/ui/ui_manager.gd" id="8_8iemx"]
|
||||
[ext_resource type="PackedScene" uid="uid://cn7tgd4y67wnd" path="res://scenes/inventory.tscn" id="8_b121j"]
|
||||
[ext_resource type="Script" uid="uid://ct5na682hxc6g" path="res://src/ui/input_listener.gd" id="9_64w2a"]
|
||||
[ext_resource type="PackedScene" uid="uid://c0cf6jkxasplk" path="res://scenes/enemy.tscn" id="10_olg7q"]
|
||||
[ext_resource type="PackedScene" uid="uid://iwn3rk6leull" path="res://scenes/pistol_pickup.tscn" id="11_t1rx8"]
|
||||
|
||||
|
@ -89,34 +91,68 @@ shape = SubResource("BoxShape3D_mx8sn")
|
|||
[node name="Interactable" type="Node3D" parent="Door"]
|
||||
script = ExtResource("3_w8frs")
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
[node name="GameUI" type="CanvasLayer" parent="."]
|
||||
follow_viewport_enabled = true
|
||||
|
||||
[node name="Control" type="Control" parent="CanvasLayer"]
|
||||
[node name="UIManager" type="Control" parent="GameUI" node_paths=PackedStringArray("inventory_menu", "context_menu")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("8_8iemx")
|
||||
inventory_menu = NodePath("Inventory")
|
||||
context_menu = NodePath("Inventory/MarginContainer/Contents/Details/ItemDescription/Container/Content/MarginContainer/ContextMenu")
|
||||
metadata/_custom_type_script = "uid://35hnuxagjlo2"
|
||||
|
||||
[node name="Control" type="Control" parent="GameUI/UIManager"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="Persistence" type="Node" parent="CanvasLayer/Control"]
|
||||
[node name="Persistence" type="Node" parent="GameUI/UIManager/Control"]
|
||||
script = ExtResource("4_mx8sn")
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/Control"]
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="GameUI/UIManager/Control"]
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="SaveButton" type="Button" parent="CanvasLayer/Control/HBoxContainer"]
|
||||
[node name="SaveButton" type="Button" parent="GameUI/UIManager/Control/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Save"
|
||||
|
||||
[node name="LoadButton" type="Button" parent="CanvasLayer/Control/HBoxContainer"]
|
||||
[node name="LoadButton" type="Button" parent="GameUI/UIManager/Control/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Load
|
||||
"
|
||||
|
||||
[node name="Inventory" parent="CanvasLayer" instance=ExtResource("8_b121j")]
|
||||
[node name="Inventory" parent="GameUI/UIManager" instance=ExtResource("8_b121j")]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
|
||||
[node name="InventoryListeners" type="Node" parent="GameUI"]
|
||||
|
||||
[node name="OpenInventory" type="Control" parent="GameUI/InventoryListeners"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
script = ExtResource("9_64w2a")
|
||||
action = &"open_inventory"
|
||||
method = 2
|
||||
metadata/_custom_type_script = "uid://ct5na682hxc6g"
|
||||
|
||||
[node name="CloseInventory" type="Control" parent="GameUI/InventoryListeners"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
script = ExtResource("9_64w2a")
|
||||
action = &"ui_close_inventory"
|
||||
metadata/_custom_type_script = "uid://ct5na682hxc6g"
|
||||
|
||||
[node name="Enemy" parent="." instance=ExtResource("10_olg7q")]
|
||||
transform = Transform3D(1.75, 0, 0, 0, 1.75, 0, 0, 0, 1.75, 6, 0, 0)
|
||||
|
@ -126,5 +162,12 @@ transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 2,
|
|||
|
||||
[connection signal="opened" from="Door" to="Door" method="hide"]
|
||||
[connection signal="interacted" from="Door/Interactable" to="Door" method="_on_interact"]
|
||||
[connection signal="pressed" from="CanvasLayer/Control/HBoxContainer/SaveButton" to="CanvasLayer/Control/Persistence" method="save" binds= ["save1.sav"]]
|
||||
[connection signal="pressed" from="CanvasLayer/Control/HBoxContainer/LoadButton" to="CanvasLayer/Control/Persistence" method="load" binds= ["save1.sav"]]
|
||||
[connection signal="pressed" from="GameUI/UIManager/Control/HBoxContainer/SaveButton" to="GameUI/UIManager/Control/Persistence" method="save" binds= ["save1.sav"]]
|
||||
[connection signal="pressed" from="GameUI/UIManager/Control/HBoxContainer/LoadButton" to="GameUI/UIManager/Control/Persistence" method="load" binds= ["save1.sav"]]
|
||||
[connection signal="pressed" from="GameUI/InventoryListeners/OpenInventory" to="GameUI/UIManager" method="open_inventory_menu"]
|
||||
|
||||
[editable path="GameUI/UIManager/Inventory"]
|
||||
[editable path="GameUI/UIManager/Inventory/MarginContainer/Contents/Details/PlayerDetails"]
|
||||
[editable path="GameUI/UIManager/Inventory/MarginContainer/Contents/Details/ItemDisplay"]
|
||||
[editable path="GameUI/UIManager/Inventory/MarginContainer/Contents/Details/ItemDescription"]
|
||||
[editable path="GameUI/UIManager/Inventory/MarginContainer/Contents/Details/ItemDescription/Container/Content/MarginContainer/ContextMenu"]
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
[gd_scene load_steps=49 format=3 uid="uid://crbrniwi6kd3p"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dpmbimh6m4ari" path="res://scenes/player_mesh.tscn" id="1_3vyb7"]
|
||||
[ext_resource type="Script" uid="uid://50vv0ta67tgl" path="res://src/player.gd" id="1_qhqgy"]
|
||||
[ext_resource type="Script" uid="uid://cngjp2wws4ld2" path="res://src/player_input.gd" id="3_dqkch"]
|
||||
[ext_resource type="Script" uid="uid://c3wlcxy4vnm2i" path="res://src/interactor.gd" id="4_dqkch"]
|
||||
[ext_resource type="Script" uid="uid://csjl56hf0fnoy" path="res://src/item_container.gd" id="5_qlg0r"]
|
||||
[ext_resource type="Script" uid="uid://k1ihjmhj7ix" path="res://src/equipment_handler.gd" id="5_smehm"]
|
||||
[ext_resource type="Script" uid="uid://50vv0ta67tgl" path="res://src/entity/player.gd" id="1_qhqgy"]
|
||||
[ext_resource type="Script" uid="uid://cngjp2wws4ld2" path="res://src/entity/player_input.gd" id="3_dqkch"]
|
||||
[ext_resource type="Script" uid="uid://c3wlcxy4vnm2i" path="res://src/world/interactor.gd" id="4_dqkch"]
|
||||
[ext_resource type="Script" path="res://src/items/item_container.gd" id="5_qlg0r"]
|
||||
[ext_resource type="Script" uid="uid://k1ihjmhj7ix" path="res://src/entity/equipment_handler.gd" id="5_smehm"]
|
||||
[ext_resource type="Resource" uid="uid://cxm3s081hnw8l" path="res://resources/player_equipment.tres" id="6_smehm"]
|
||||
[ext_resource type="Resource" uid="uid://bllq6ri54q3ne" path="res://resources/player_inventory.tres" id="6_tuyoq"]
|
||||
|
||||
|
|
5
godot/src/attributes/ammo_attribute.gd
Normal file
5
godot/src/attributes/ammo_attribute.gd
Normal file
|
@ -0,0 +1,5 @@
|
|||
class_name AmmoAttribute extends Attribute
|
||||
|
||||
@export var ammo_type: Item
|
||||
@export var max_capacity: int
|
||||
|
1
godot/src/attributes/ammo_attribute.gd.uid
Normal file
1
godot/src/attributes/ammo_attribute.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://bbigpwchxitb5
|
1
godot/src/attributes/attribute.gd
Normal file
1
godot/src/attributes/attribute.gd
Normal file
|
@ -0,0 +1 @@
|
|||
class_name Attribute extends Resource
|
1
godot/src/attributes/attribute.gd.uid
Normal file
1
godot/src/attributes/attribute.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://d1imxjix6ljul
|
2
godot/src/attributes/combinable_attribute.gd
Normal file
2
godot/src/attributes/combinable_attribute.gd
Normal file
|
@ -0,0 +1,2 @@
|
|||
class_name CombinableAttribute extends Attribute
|
||||
|
1
godot/src/attributes/combinable_attribute.gd.uid
Normal file
1
godot/src/attributes/combinable_attribute.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://dfkjh55qql76v
|
13
godot/src/attributes/equippable_attribute.gd
Normal file
13
godot/src/attributes/equippable_attribute.gd
Normal file
|
@ -0,0 +1,13 @@
|
|||
class_name EquippableAttribute extends Attribute
|
||||
|
||||
enum Type {
|
||||
PRIMARY,
|
||||
SECONDARY
|
||||
}
|
||||
|
||||
@export var type: Type = Type.PRIMARY
|
||||
|
||||
func equip_to(equipment: Equipment, item: Item):
|
||||
match type:
|
||||
Type.PRIMARY: equipment.primary = Option.some(item)
|
||||
Type.SECONDARY: equipment.secondary = Option.some(item)
|
1
godot/src/attributes/equippable_attribute.gd.uid
Normal file
1
godot/src/attributes/equippable_attribute.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://c1y3loxtmkeg3
|
2
godot/src/attributes/usable_attribute.gd
Normal file
2
godot/src/attributes/usable_attribute.gd
Normal file
|
@ -0,0 +1,2 @@
|
|||
class_name UsableAttribute extends Attribute
|
||||
|
1
godot/src/attributes/usable_attribute.gd.uid
Normal file
1
godot/src/attributes/usable_attribute.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://dpyiysj7aigc3
|
|
@ -67,3 +67,5 @@ func on_before_load():
|
|||
func on_load(data: Dictionary):
|
||||
position = data.position
|
||||
rotation = data.rotation
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
class_name InputListener extends Control
|
||||
|
||||
enum ActionEvent {
|
||||
Pressed,
|
||||
Released
|
||||
}
|
||||
|
||||
signal opened
|
||||
signal closed
|
||||
|
||||
@export var input_event: ActionEvent
|
||||
@export var open_action: StringName
|
||||
@export var close_action: StringName
|
||||
|
||||
func _is_active(event: InputEvent, action: StringName) -> bool:
|
||||
match input_event:
|
||||
ActionEvent.Pressed: return event.is_action_pressed(action)
|
||||
ActionEvent.Released: return event.is_action_released(action)
|
||||
_: return false
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if _is_active(event, open_action):
|
||||
accept_event()
|
||||
opened.emit()
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if _is_active(event, close_action):
|
||||
accept_event()
|
||||
closed.emit()
|
|
@ -1 +0,0 @@
|
|||
uid://bbkm8bt2mrq1c
|
|
@ -1,67 +0,0 @@
|
|||
class_name ItemDetailsUI extends HBoxContainer
|
||||
|
||||
@export var equipment: Equipment
|
||||
@export var viewport: SubViewport
|
||||
@export var description_label: Label
|
||||
@export var action_menu: Control
|
||||
|
||||
var current_item: Option = Option.none
|
||||
|
||||
var _displayed_item: Node3D
|
||||
var _default_description: String
|
||||
|
||||
func _ready() -> void:
|
||||
action_menu.hide()
|
||||
_default_description = description_label.text
|
||||
|
||||
func _set_default():
|
||||
if _displayed_item != null:
|
||||
viewport.remove_child(_displayed_item)
|
||||
_displayed_item.queue_free()
|
||||
description_label.text = _default_description
|
||||
|
||||
func _on_updated(item: Option):
|
||||
current_item = item
|
||||
if item.is_some():
|
||||
var _item: Item = item.unwrap()
|
||||
match _item.create_preview():
|
||||
var x when x.is_some():
|
||||
_displayed_item = x.unwrap()
|
||||
viewport.add_child(_displayed_item)
|
||||
_: _set_default()
|
||||
description_label.text = _item.description
|
||||
else:
|
||||
_set_default()
|
||||
|
||||
func _on_selected(_item: Item):
|
||||
action_menu.show()
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_FOCUS_EXIT:
|
||||
action_menu.hide()
|
||||
|
||||
func _is_equip(item: Item) -> bool:
|
||||
return is_instance_of(item, EquippableItem)
|
||||
|
||||
func _already_equipped(item: Item) -> bool:
|
||||
return equipment.is_equipped(item)
|
||||
|
||||
func use():
|
||||
if current_item.is_some():
|
||||
var item = current_item.unwrap()
|
||||
if _is_equip(item):
|
||||
if _already_equipped(item):
|
||||
equipment.unequip_item(item)
|
||||
else:
|
||||
equipment.equip(item)
|
||||
else:
|
||||
item.use()
|
||||
action_menu.hide()
|
||||
|
||||
func combine():
|
||||
current_item.inspect(func(x): x.combine())
|
||||
action_menu.hide()
|
||||
|
||||
func inspect():
|
||||
current_item.inspect(func(x): x.inspect())
|
||||
action_menu.hide()
|
|
@ -1,11 +1,11 @@
|
|||
class_name Equipment extends Resource
|
||||
|
||||
signal unequipped_primary(equipment: EquippableItem)
|
||||
signal equipped_primary(equipment: EquippableItem)
|
||||
signal unequipped_secondary(equipment: EquippableItem)
|
||||
signal equipped_secondary(equipment: EquippableItem)
|
||||
signal unequipped_primary(equipment: Item)
|
||||
signal equipped_primary(equipment: Item)
|
||||
signal unequipped_secondary(equipment: Item)
|
||||
signal equipped_secondary(equipment: Item)
|
||||
|
||||
@export var _primary: EquippableItem
|
||||
@export var _primary: Item
|
||||
|
||||
var primary: Option:
|
||||
get: return Option.from(_primary)
|
||||
|
@ -17,7 +17,7 @@ func _unequip_primary():
|
|||
_primary = null
|
||||
unequipped_primary.emit(previous)
|
||||
|
||||
func _equip_primary(item: EquippableItem):
|
||||
func _equip_primary(item: Item):
|
||||
if _primary != null:
|
||||
_unequip_primary()
|
||||
|
||||
|
@ -31,7 +31,7 @@ func set_primary(item: Option):
|
|||
_equip_primary(x.unwrap())
|
||||
_: _unequip_primary()
|
||||
|
||||
@export var _secondary: EquippableItem
|
||||
@export var _secondary: Item
|
||||
|
||||
var secondary: Option:
|
||||
get: return Option.from(_secondary)
|
||||
|
@ -43,7 +43,7 @@ func _unequip_secondary():
|
|||
_secondary = null
|
||||
unequipped_secondary.emit(previous)
|
||||
|
||||
func _equip_secondary(item: EquippableItem):
|
||||
func _equip_secondary(item: Item):
|
||||
if _secondary != null:
|
||||
_unequip_secondary()
|
||||
|
||||
|
@ -67,24 +67,24 @@ func _ready():
|
|||
if _secondary != null:
|
||||
_equip_secondary(_secondary)
|
||||
|
||||
func equip(item: EquippableItem):
|
||||
func equip(item: Item):
|
||||
match item.type:
|
||||
EquippableItem.EquipmentType.PRIMARY: primary = Option.some(item)
|
||||
EquippableItem.EquipmentType.SECONDARY: secondary = Option.some(item)
|
||||
EquippableAttribute.Type.PRIMARY: primary = Option.some(item)
|
||||
EquippableAttribute.Type.SECONDARY: secondary = Option.some(item)
|
||||
|
||||
func unequip(equip_type: EquippableItem.EquipmentType):
|
||||
func unequip(equip_type: EquippableAttribute.Type):
|
||||
match equip_type:
|
||||
EquippableItem.EquipmentType.PRIMARY: primary = Option.none
|
||||
EquippableItem.EquipmentType.SECONDARY:secondary = Option.none
|
||||
EquippableAttribute.Type.PRIMARY: primary = Option.none
|
||||
EquippableAttribute.Type.SECONDARY:secondary = Option.none
|
||||
|
||||
func unequip_item(item: EquippableItem):
|
||||
func unequip_item(item: Item):
|
||||
equipped_to(item).inspect(unequip)
|
||||
|
||||
func is_equipped(item: EquippableItem) -> bool:
|
||||
func is_equipped(item: Item) -> bool:
|
||||
return equipped_to(item).is_some()
|
||||
|
||||
func equipped_to(item: EquippableItem) -> Option:
|
||||
func equipped_to(item: Item) -> Option:
|
||||
match item.type:
|
||||
EquippableItem.EquipmentType.PRIMARY when item == _primary: return Option.some(EquippableItem.EquipmentType.PRIMARY)
|
||||
EquippableItem.EquipmentType.SECONDARY when item == _secondary: return Option.some(EquippableItem.EquipmentType.SECONDARY)
|
||||
EquippableAttribute.Type.PRIMARY when item == _primary: return Option.some(EquippableItem.EquipmentType.PRIMARY)
|
||||
EquippableAttribute.Type.SECONDARY when item == _secondary: return Option.some(EquippableItem.EquipmentType.SECONDARY)
|
||||
return Option.none
|
|
@ -6,6 +6,14 @@ enum EquipmentType {
|
|||
}
|
||||
|
||||
@export var type: EquipmentType = EquipmentType.PRIMARY
|
||||
@export var ammo_type: Item
|
||||
@export var ammo_capacity: int
|
||||
|
||||
var uses_ammo: bool:
|
||||
get: return ammo_type != null
|
||||
|
||||
var display_ammo: bool:
|
||||
get: return ammo_capacity < 2
|
||||
|
||||
func is_primary() -> bool:
|
||||
return type == EquipmentType.PRIMARY
|
|
@ -6,6 +6,7 @@ class_name Item extends Resource
|
|||
@export var icon: Texture2D
|
||||
@export var scene: PackedScene
|
||||
@export var preview_scene: PackedScene
|
||||
@export var attributes: Array[Attribute] = []
|
||||
|
||||
func _to_string() -> String:
|
||||
var icon_path = _resource_path_name(icon)
|
||||
|
@ -29,9 +30,19 @@ func create() -> Option:
|
|||
func create_preview() -> Option:
|
||||
return _create(preview_scene)
|
||||
|
||||
func inspect():
|
||||
pass
|
||||
|
||||
func combine(_with: Item) -> bool:
|
||||
func has_attribute(type: Variant) -> bool:
|
||||
for value in attributes:
|
||||
if is_instance_of(value, type):
|
||||
return true
|
||||
return false
|
||||
return ListIterator.from_array(attributes).any(func(x): return is_instance_of(x, type))
|
||||
|
||||
func get_attribute(type: Variant) -> Option:
|
||||
return ListIterator.from_array(attributes).find(func(x): is_instance_of(x, type))
|
||||
|
||||
func get_attributes(type: Variant) -> Iterator:
|
||||
return ListIterator.from_array(attributes).filter(func(x): is_instance_of(x, type))
|
||||
|
||||
func use() -> bool:
|
||||
return false
|
|
@ -1,38 +1,48 @@
|
|||
class_name NodeExt
|
||||
class NodeChildIterator:
|
||||
var _node: Node
|
||||
var _include_internal: bool
|
||||
var _index: int
|
||||
var _length: int
|
||||
var _node: Node
|
||||
var _include_internal: bool
|
||||
var _index: int
|
||||
var _length: int
|
||||
|
||||
func _init(node: Node, include_internal: bool) -> void:
|
||||
_node = node
|
||||
_include_internal = include_internal
|
||||
_index = 0
|
||||
_length = node.get_child_count(include_internal)
|
||||
func _init(node: Node, include_internal: bool) -> void:
|
||||
_node = node
|
||||
_include_internal = include_internal
|
||||
_index = 0
|
||||
_length = node.get_child_count(include_internal)
|
||||
|
||||
func _continue() -> bool:
|
||||
return (_index < _length)
|
||||
func _continue() -> bool:
|
||||
return (_index < _length)
|
||||
|
||||
func _iter_init(_iter: Array) -> bool:
|
||||
_index = 0
|
||||
return _continue()
|
||||
func _iter_init(_iter: Array) -> bool:
|
||||
_index = 0
|
||||
return _continue()
|
||||
|
||||
func _iter_next(_iter: Array) -> bool:
|
||||
_index += 1
|
||||
return _continue()
|
||||
func _iter_next(_iter: Array) -> bool:
|
||||
_index += 1
|
||||
return _continue()
|
||||
|
||||
func _iter_get(_iter: Variant) -> Variant:
|
||||
return _node.get_child(_index, _include_internal)
|
||||
func _iter_get(_iter: Variant) -> Variant:
|
||||
return _node.get_child(_index, _include_internal)
|
||||
|
||||
static func find_child(node: Node, predicate: Callable, include_internal: bool = false) -> Option:
|
||||
for child in NodeChildIterator.new(node, include_internal):
|
||||
if predicate.call(child):
|
||||
return Option.some(child)
|
||||
return Option.none
|
||||
for child in NodeChildIterator.new(node, include_internal):
|
||||
if predicate.call(child):
|
||||
return Option.some(child)
|
||||
return Option.none
|
||||
|
||||
static func find_children(node: Node, predicate: Callable, include_internal: bool = false) -> Array[Node]:
|
||||
var results: Array[Node] = []
|
||||
for child in NodeChildIterator.new(node, include_internal):
|
||||
if predicate.call(child):
|
||||
results.append(child)
|
||||
return results
|
||||
|
||||
static func find_children_variant(node: Node, variant: Variant, include_internal: bool = false) -> Array[Node]:
|
||||
return find_children(node, func(child: Node) -> bool: return is_instance_of(child, variant), include_internal)
|
||||
|
||||
static func find_child_variant(node: Node, variant: Variant, include_internal: bool = false) -> Option:
|
||||
for child in NodeChildIterator.new(node, include_internal):
|
||||
if is_instance_of(child, variant):
|
||||
return Option.some(child)
|
||||
return Option.none
|
||||
for child in NodeChildIterator.new(node, include_internal):
|
||||
if is_instance_of(child, variant):
|
||||
return Option.some(child)
|
||||
return Option.none
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
class_name RootControl extends InputListener
|
||||
|
||||
func _ready() -> void:
|
||||
if self.focus_mode == Control.FOCUS_NONE:
|
||||
self.focus_mode = Control.FOCUS_ALL
|
||||
|
||||
opened.connect(open)
|
||||
closed.connect(close)
|
||||
|
||||
if visible:
|
||||
grab_focus()
|
||||
|
||||
func open():
|
||||
show()
|
||||
grab_focus()
|
||||
|
||||
func close():
|
||||
hide()
|
||||
release_focus()
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
super(event)
|
||||
KCUtils.propagate_input_event(self, "_gui_input", event, false)
|
7
godot/src/ui/box.gd
Normal file
7
godot/src/ui/box.gd
Normal file
|
@ -0,0 +1,7 @@
|
|||
class_name Box extends PanelContainer
|
||||
|
||||
@export var title_label: Label
|
||||
@export var body_container: Control
|
||||
|
||||
func add_content(content: Control) -> void:
|
||||
body_container.add_child(content)
|
1
godot/src/ui/box.gd.uid
Normal file
1
godot/src/ui/box.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://bnumwlio6adb8
|
|
@ -6,4 +6,4 @@ func _gui_input(event: InputEvent) -> void:
|
|||
if event.is_action_pressed(cancel_action):
|
||||
accept_event()
|
||||
release_focus()
|
||||
KCUtils.notify(get_parent(), NOTIFICATION_FOCUS_EXIT, true)
|
||||
K.notify(get_parent(), NOTIFICATION_FOCUS_EXIT, true)
|
7
godot/src/ui/context_menu.gd
Normal file
7
godot/src/ui/context_menu.gd
Normal file
|
@ -0,0 +1,7 @@
|
|||
class_name ContextMenu extends Control
|
||||
|
||||
signal requested_close
|
||||
|
||||
func set_options_for(item: Item):
|
||||
pass
|
||||
|
1
godot/src/ui/context_menu.gd.uid
Normal file
1
godot/src/ui/context_menu.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://c71q7htypy0i8
|
20
godot/src/ui/input_group_listener.gd
Normal file
20
godot/src/ui/input_group_listener.gd
Normal file
|
@ -0,0 +1,20 @@
|
|||
class_name InputGroupListener extends Node
|
||||
|
||||
signal pressed
|
||||
signal released
|
||||
|
||||
var listeners: Array[InputListener]
|
||||
|
||||
func _ready() -> void:
|
||||
listeners.assign(NodeExt.find_children_variant(self, InputListener))
|
||||
|
||||
for listener in listeners:
|
||||
listener.pressed.connect(_on_pressed)
|
||||
listener.released.connect(_on_released)
|
||||
|
||||
func _on_pressed() -> void:
|
||||
pressed.emit()
|
||||
|
||||
func _on_released() -> void:
|
||||
released.emit()
|
||||
|
57
godot/src/ui/input_listener.gd
Normal file
57
godot/src/ui/input_listener.gd
Normal file
|
@ -0,0 +1,57 @@
|
|||
class_name InputListener extends Control
|
||||
|
||||
enum InputMethod {
|
||||
GUI_INPUT,
|
||||
INPUT,
|
||||
UNHANDLED_INPUT,
|
||||
UNHANDLED_KEY_INPUT
|
||||
}
|
||||
|
||||
signal pressed
|
||||
signal released
|
||||
|
||||
@export var action: StringName
|
||||
@export var method: InputMethod = InputMethod.INPUT
|
||||
|
||||
func _ready() -> void:
|
||||
set_process_input(false)
|
||||
set_process_unhandled_input(false)
|
||||
set_process_unhandled_key_input(false)
|
||||
|
||||
set_enabled(true)
|
||||
|
||||
func set_enabled(enabled: bool) -> void:
|
||||
match method:
|
||||
InputMethod.GUI_INPUT | InputMethod.INPUT: set_process_input(enabled)
|
||||
InputMethod.UNHANDLED_INPUT: set_process_unhandled_input(enabled)
|
||||
InputMethod.UNHANDLED_KEY_INPUT: set_process_unhandled_key_input(enabled)
|
||||
|
||||
func enable() -> void:
|
||||
set_enabled(true)
|
||||
|
||||
func disable() -> void:
|
||||
set_enabled(false)
|
||||
|
||||
func _test_action(event: InputEvent):
|
||||
if event.is_action_pressed(action):
|
||||
if pressed.has_connections():
|
||||
pressed.emit()
|
||||
accept_event()
|
||||
elif event.is_action_released(action):
|
||||
if released.has_connections():
|
||||
released.emit()
|
||||
accept_event()
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if method == InputMethod.GUI_INPUT:
|
||||
_test_action(event)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if method == InputMethod.INPUT:
|
||||
_test_action(event)
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
_test_action(event)
|
||||
|
||||
func _unhandled_key_input(event: InputEvent) -> void:
|
||||
_test_action(event)
|
79
godot/src/ui/inventory_screen.gd
Normal file
79
godot/src/ui/inventory_screen.gd
Normal file
|
@ -0,0 +1,79 @@
|
|||
class_name InventoryScreen extends Control
|
||||
|
||||
signal item_selected(item: Item)
|
||||
signal requested_close
|
||||
|
||||
@export_group("Dependencies")
|
||||
@export var inventory: Inventory
|
||||
@export var equipment: Equipment
|
||||
|
||||
@export_group("Carousel")
|
||||
@export var inventory_item_scene: PackedScene
|
||||
@export var carousel: IndexCarousel
|
||||
@export var item_details: ItemDetailUI
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_connect_signals()
|
||||
|
||||
func _connect_signals() -> void:
|
||||
inventory.updated.connect(_build_carousel)
|
||||
carousel.index_changed.connect(_on_item_changed)
|
||||
|
||||
enum Direction {
|
||||
Right = 1,
|
||||
Left = -1
|
||||
}
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed(PlayerInput.UIAction.Right):
|
||||
move_carousel(Direction.Right)
|
||||
accept_event()
|
||||
elif event.is_action_pressed(PlayerInput.UIAction.Left):
|
||||
move_carousel(Direction.Left)
|
||||
accept_event()
|
||||
elif event.is_action_pressed(PlayerInput.UIAction.Accept):
|
||||
_items().nth(carousel.current_index).inspect(item_selected.emit)
|
||||
accept_event()
|
||||
|
||||
func _items() -> Iterator:
|
||||
return inventory.iter().map(func(x): return x.value.item)
|
||||
|
||||
func _build_carousel() -> void:
|
||||
K.remove_children(carousel)
|
||||
|
||||
var empty_iter = Iterator.repeat(null).take(inventory.empty_slots)
|
||||
var item_iter = ListIterator.from_array(inventory.items.values().map(func(x): return x.item))
|
||||
|
||||
for item in item_iter.fuse(empty_iter):
|
||||
var scene = inventory_item_scene.instantiate()
|
||||
var option = Option.from(item)
|
||||
bind_item(scene, option)
|
||||
carousel.add_child(scene)
|
||||
|
||||
func bind_item(node: Node, item: Option) -> void:
|
||||
if node.has_method('bind'):
|
||||
node.bind(item)
|
||||
|
||||
func move_carousel(delta: int):
|
||||
var next_index = carousel.get_carousel_index() + delta
|
||||
carousel.go_to_index(next_index)
|
||||
|
||||
func close():
|
||||
requested_close.emit()
|
||||
|
||||
func _on_item_changed(index: int) -> void:
|
||||
item_details.set_item(_items().nth(index))
|
||||
|
||||
func _use() -> void:
|
||||
pass
|
||||
|
||||
func _equip() -> void:
|
||||
pass
|
||||
|
||||
func _combine() -> void:
|
||||
pass
|
||||
|
||||
func _inspect() -> void:
|
||||
pass
|
||||
|
1
godot/src/ui/inventory_screen.gd.uid
Normal file
1
godot/src/ui/inventory_screen.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://b7j7weoa8tikm
|
1
godot/src/ui/inventory_screen.uid
Normal file
1
godot/src/ui/inventory_screen.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://bjwhkpqabr7sg
|
|
@ -21,7 +21,7 @@ func _on_item_changed(index: int) -> void:
|
|||
_: item_focused.emit(Option.none)
|
||||
|
||||
func _build_carousel() -> void:
|
||||
KCUtils.remove_children(carousel)
|
||||
K.remove_children(carousel)
|
||||
|
||||
var empty_iter = Iterator.repeat(null).take(inventory.empty_slots)
|
||||
var item_iter = ListIterator.from_array(inventory.items.values().map(func(x): return x.item))
|
35
godot/src/ui/item_detail_ui.gd
Normal file
35
godot/src/ui/item_detail_ui.gd
Normal file
|
@ -0,0 +1,35 @@
|
|||
class_name ItemDetailUI extends HBoxContainer
|
||||
|
||||
@export var viewport: SubViewport
|
||||
@export var description_label: Label
|
||||
|
||||
var current_item: Option = Option.none
|
||||
|
||||
var _displayed_item: Node3D
|
||||
var _default_description: String
|
||||
|
||||
func _ready() -> void:
|
||||
_default_description = description_label.text
|
||||
|
||||
func _set_default():
|
||||
if _displayed_item != null:
|
||||
viewport.remove_child(_displayed_item)
|
||||
_displayed_item.queue_free()
|
||||
description_label.text = _default_description
|
||||
|
||||
func set_item(item: Option):
|
||||
current_item = item
|
||||
if item.is_some():
|
||||
var _item: Item = item.unwrap()
|
||||
match _item.create_preview():
|
||||
var x when x.is_some():
|
||||
_displayed_item = x.unwrap()
|
||||
viewport.add_child(_displayed_item)
|
||||
_: _set_default()
|
||||
description_label.text = _item.description
|
||||
else:
|
||||
clear_item()
|
||||
|
||||
|
||||
func clear_item():
|
||||
_set_default()
|
|
@ -1,4 +1,4 @@
|
|||
class_name ItemUI extends Control
|
||||
class_name ItemSlotUI extends Control
|
||||
|
||||
@export var name_label: Label
|
||||
@export var icon_texture: TextureRect
|
27
godot/src/ui/item_ui.gd
Normal file
27
godot/src/ui/item_ui.gd
Normal file
|
@ -0,0 +1,27 @@
|
|||
class_name ItemUI extends Control
|
||||
|
||||
@export var _title_label: Label
|
||||
@export var _icon_texture: TextureRect
|
||||
|
||||
var _default_title: String
|
||||
var _default_icon: Texture2D
|
||||
|
||||
func _ready() -> void:
|
||||
_default_title = _title_label.text
|
||||
_default_icon = _icon_texture.texture
|
||||
|
||||
func _set_default() -> void:
|
||||
_title_label.text = _default_title
|
||||
_icon_texture.texture = _default_icon
|
||||
|
||||
func bind(item: Option) -> void:
|
||||
match item:
|
||||
var x when x.is_some():
|
||||
print(x)
|
||||
var _item = x.unwrap()
|
||||
_title_label.text = _item.name
|
||||
_icon_texture.texture = _item.icon
|
||||
_: _set_default()
|
||||
|
||||
func clear() -> void:
|
||||
_set_default()
|
1
godot/src/ui/item_ui.gd.uid
Normal file
1
godot/src/ui/item_ui.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://c2yaayl4msnf1
|
159
godot/src/ui/ui_manager.gd
Normal file
159
godot/src/ui/ui_manager.gd
Normal file
|
@ -0,0 +1,159 @@
|
|||
class_name UIManager extends Control
|
||||
|
||||
@export var inventory_menu: Control
|
||||
@export var context_menu: Control
|
||||
|
||||
class StackFrame extends RefCounted:
|
||||
var root: Control
|
||||
var children: Array[Control] = []
|
||||
|
||||
func _init(element: Control) -> void:
|
||||
root = element
|
||||
|
||||
var stack: Array[StackFrame] = []
|
||||
|
||||
func _ready() -> void:
|
||||
if inventory_menu.has_signal('requested_close'):
|
||||
inventory_menu.requested_close.connect(close_inventory_menu)
|
||||
#if context_menu.has_signal('requested_close'):
|
||||
# context_menu.requested_close.connect(close_context_menu)
|
||||
|
||||
func get_current_frame() -> Option:
|
||||
if stack.is_empty(): return Option.none
|
||||
else: return Option.some(stack.back())
|
||||
|
||||
func _focus_current_frame(frame: StackFrame) -> void:
|
||||
if not frame.children.is_empty():
|
||||
frame.children.back().grab_focus()
|
||||
else:
|
||||
frame.root.grab_focus()
|
||||
|
||||
func focus_current_frame() -> void:
|
||||
get_current_frame().inspect(_focus_current_frame)
|
||||
|
||||
func clamp_rect(rect: Rect2) -> Rect2:
|
||||
var result = Rect2(rect)
|
||||
var viewport_rect = get_viewport().get_visible_rect()
|
||||
|
||||
if result.end.x > viewport_rect.size.x:
|
||||
result.x = viewport_rect.size.x - result.size.x
|
||||
|
||||
result.position.x = maxf(0, rect.position.x)
|
||||
|
||||
if result.end.y > viewport_rect.size.y:
|
||||
result.y = viewport_rect.size.y - result.size.y
|
||||
|
||||
result.position.y = maxf(0, rect.position.y)
|
||||
|
||||
return result
|
||||
|
||||
func open_inventory_menu() -> void:
|
||||
if is_open(inventory_menu):
|
||||
return
|
||||
var new_frame = StackFrame.new(inventory_menu)
|
||||
stack.append(new_frame)
|
||||
inventory_menu.show()
|
||||
inventory_menu.grab_focus()
|
||||
|
||||
func close_inventory_menu() -> void:
|
||||
_handle_root_ui_closed(inventory_menu)
|
||||
|
||||
func open_context_menu(_position: Vector2, content: Control) -> void:
|
||||
if stack.is_empty():
|
||||
push_error("can't open context menu. no active windows")
|
||||
return
|
||||
|
||||
var current_frame = get_current_frame()
|
||||
|
||||
var clamped_rect = clamp_rect(Rect2(_position, context_menu.size))
|
||||
context_menu.global_position = clamped_rect.position
|
||||
context_menu.set_content(content)
|
||||
|
||||
current_frame.children.append(context_menu)
|
||||
|
||||
context_menu.show()
|
||||
context_menu.grab_focus()
|
||||
|
||||
func close_context_menu() -> void:
|
||||
_handle_child_closed(context_menu)
|
||||
|
||||
func is_open(element: Control) -> bool:
|
||||
for i in range(stack.size()):
|
||||
if stack[i].root == element:
|
||||
return true
|
||||
return false
|
||||
|
||||
func _remove_element(element: Control) -> void:
|
||||
var frame_to_close: StackFrame = null
|
||||
var frame_index: int = -1
|
||||
|
||||
for i in range(stack.size()):
|
||||
if stack[i].root == element:
|
||||
frame_to_close = stack[i]
|
||||
frame_index = i
|
||||
break
|
||||
|
||||
if frame_to_close:
|
||||
_close_frame(frame_to_close, frame_index)
|
||||
else:
|
||||
push_warning("'%s' requested to be closed but was not found as a root UI in any stack frame." % element.name)
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed(PlayerInput.UIAction.Cancel):
|
||||
var current_frame_option = get_current_frame()
|
||||
if current_frame_option.is_some():
|
||||
var current_frame = current_frame_option.unwrap()
|
||||
if not current_frame.children.is_empty():
|
||||
var top_child = current_frame.children.back()
|
||||
if top_child.has_method("cancel"):
|
||||
top_child.handle_cancel()
|
||||
else:
|
||||
top_child.hide()
|
||||
current_frame.children.pop_back()
|
||||
focus_current_frame()
|
||||
else:
|
||||
var root_element = current_frame.root
|
||||
if root_element.has_method("cancel"):
|
||||
root_element.handle_cancel()
|
||||
else:
|
||||
root_element.hide()
|
||||
stack.pop_back()
|
||||
focus_current_frame()
|
||||
|
||||
accept_event()
|
||||
|
||||
func _handle_child_closed(child: Control) -> void:
|
||||
if stack.is_empty(): return
|
||||
var current_frame = get_current_frame().unwrap()
|
||||
|
||||
if not current_frame.children.is_empty() and current_frame.children.back() == child:
|
||||
current_frame.children.pop_back()
|
||||
child.hide()
|
||||
focus_current_frame()
|
||||
else:
|
||||
push_warning("A child window '%s' requested to be closed but was not the top-most child of the current stack frame." % child.name)
|
||||
|
||||
func _handle_root_ui_closed(root_ui: Control) -> void:
|
||||
var frame_index = -1
|
||||
for i in range(stack.size()):
|
||||
if stack[i].root == root_ui:
|
||||
frame_index = i
|
||||
break
|
||||
|
||||
if frame_index != -1:
|
||||
_close_frame(stack[frame_index], frame_index)
|
||||
else:
|
||||
push_warning("Root UI '%s' closed but its frame was not found in the stack." % root_ui.name)
|
||||
|
||||
|
||||
func _close_frame(frame: StackFrame, index: int) -> void:
|
||||
frame.root.hide()
|
||||
for i in range(frame.children.size() -1, -1, -1):
|
||||
var child = frame.children[i]
|
||||
if is_instance_valid(child):
|
||||
child.hide()
|
||||
frame.children.clear()
|
||||
|
||||
stack.remove_at(index)
|
||||
focus_current_frame()
|
||||
|
1
godot/src/ui/ui_manager.gd.uid
Normal file
1
godot/src/ui/ui_manager.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://35hnuxagjlo2
|
|
@ -1 +0,0 @@
|
|||
uid://bxd483uvo31jf
|
Loading…
Add table
Reference in a new issue