Untested PickupableItem

This commit is contained in:
Alexey 2025-07-31 15:33:31 +03:00
commit 63e87e86d5
19 changed files with 200 additions and 17 deletions

View file

@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="WeaponPickupableResource" load_steps=3 format=3 uid="uid://cdsrjmq8xd5b0"]
[ext_resource type="Script" uid="uid://dob8q3jclxrtd" path="res://base/scripts/interactive/weapon_pickupable_resource.gd" id="1_7xmtm"]
[ext_resource type="PackedScene" uid="uid://cig5dryfni4f8" path="res://base/scenes/weapons/auto_weapon_test.tscn" id="2_qbjol"]
[resource]
script = ExtResource("1_7xmtm")
weapon = ExtResource("2_qbjol")
id = &"auto_weapon_test"
metadata/_custom_type_script = "uid://dob8q3jclxrtd"

View file

@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="WeaponPickupableResource" load_steps=3 format=3 uid="uid://b1pqbhcv5ixmy"]
[ext_resource type="Script" uid="uid://dob8q3jclxrtd" path="res://base/scripts/interactive/weapon_pickupable_resource.gd" id="1_fp2lr"]
[ext_resource type="PackedScene" uid="uid://bb6ovrbusyxpi" path="res://base/scenes/weapons/weapon_base.tscn" id="2_fp2lr"]
[resource]
script = ExtResource("1_fp2lr")
weapon = ExtResource("2_fp2lr")
id = &"weapon_base"
metadata/_custom_type_script = "uid://dob8q3jclxrtd"

View file

@ -1,6 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://ddjjrkernsobh"]
[gd_scene load_steps=4 format=3 uid="uid://ddjjrkernsobh"]
[ext_resource type="Texture2D" uid="uid://bdgoa18kfhlwo" path="res://base/assets/sprites/interactive/interactive.png" id="1_yf10f"]
[ext_resource type="Script" uid="uid://fva8kqc3mk86" path="res://base/scripts/interactive_object.gd" id="2_cdwk3"]
[sub_resource type="SphereShape3D" id="SphereShape3D_cdwk3"]
@ -9,8 +10,12 @@ pixel_size = 0.0313
billboard = 1
texture_filter = 0
texture = ExtResource("1_yf10f")
script = ExtResource("2_cdwk3")
[node name="Area3D" type="Area3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"]
shape = SubResource("SphereShape3D_cdwk3")
[connection signal="body_entered" from="Area3D" to="." method="_on_body_entered"]
[connection signal="body_exited" from="Area3D" to="." method="_on_body_exited"]

View file

@ -0,0 +1,21 @@
[gd_scene load_steps=4 format=3 uid="uid://c4wpq5gxkbor7"]
[ext_resource type="Texture2D" uid="uid://bdgoa18kfhlwo" path="res://base/assets/sprites/interactive/interactive.png" id="1_2373a"]
[ext_resource type="Script" uid="uid://v2v4keo0ydlc" path="res://base/scripts/interactive/pickupable_item.gd" id="2_2373a"]
[sub_resource type="SphereShape3D" id="SphereShape3D_cdwk3"]
[node name="PickupableItem" type="Sprite3D"]
pixel_size = 0.0313
billboard = 1
texture_filter = 0
texture = ExtResource("1_2373a")
script = ExtResource("2_2373a")
[node name="Area3D" type="Area3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"]
shape = SubResource("SphereShape3D_cdwk3")
[connection signal="body_entered" from="Area3D" to="." method="_on_body_entered"]
[connection signal="body_exited" from="Area3D" to="." method="_on_body_exited"]

View file

@ -9,6 +9,21 @@
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_jjqxs"]
[sub_resource type="Animation" id="Animation_gt0rj"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("HUD/Weapon:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 0)]
}
[sub_resource type="Animation" id="Animation_8sdfx"]
resource_name = "default"
length = 1.33334
@ -27,21 +42,6 @@ tracks/0/keys = {
"values": [Vector2(0, 0), Vector2(16, 32), Vector2(0, 0), Vector2(32, 32), Vector2(0, 0)]
}
[sub_resource type="Animation" id="Animation_gt0rj"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("HUD/Weapon:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 0)]
}
[sub_resource type="Animation" id="Animation_juj2l"]
resource_name = "static"
step = 0.0

View file

@ -1,4 +1,7 @@
[gd_scene format=3 uid="uid://bgnb01j1nphhi"]
[gd_scene load_steps=3 format=3 uid="uid://bgnb01j1nphhi"]
[ext_resource type="PackedScene" uid="uid://c4wpq5gxkbor7" path="res://base/scenes/interactive/pickupable_item.tscn" id="1_1whpt"]
[ext_resource type="Resource" uid="uid://b1pqbhcv5ixmy" path="res://base/assets/resources/items/weapon_base.tres" id="2_ayew2"]
[node name="Test Room" type="Node3D"]
@ -41,3 +44,11 @@ size = Vector3(0.2, 4, 4)
[node name="SpotLight3D" type="SpotLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 2.6, 0)
spot_angle = 90.0
[node name="PickupableItem" parent="." instance=ExtResource("1_1whpt")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.992068, -0.47008, -0.800458)
content = ExtResource("2_ayew2")
[node name="PickupableItem2" parent="." instance=ExtResource("1_1whpt")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.700438, -0.47008, -0.800458)
content = ExtResource("2_ayew2")

View file

@ -0,0 +1,13 @@
extends Resource
class_name BasePickupableResource
## Item ID, make sure it's unique
@export var id: StringName
## Texture that will be used in node sprite
@export var texture: Texture2D
## Emitted when item picked up. Returns if PickupableItem should be freed
func _apply(_player: Player) -> bool:
return true

View file

@ -0,0 +1 @@
uid://cfovybsk5c606

View file

@ -0,0 +1,26 @@
extends Sprite3D
class_name InteractiveObject
var player: Player = null
func _ready() -> void:
pass
func _process(_delta: float) -> void:
if player == null:
return
if Input.is_action_just_pressed('interact'):
_interact(player)
func _on_body_entered(body: Node3D) -> void:
if body is Player:
player = body
func _on_body_exited(body: Node3D) -> void:
if body is Player:
player = null
## Invoked when interact action was used when player is in object's area
func _interact(_player: Player) -> void:
pass

View file

@ -0,0 +1 @@
uid://junnt60g6c7x

View file

@ -0,0 +1,13 @@
extends InteractiveObject
class_name PickupableItem
@export var content: BasePickupableResource
func _ready() -> void:
if content.texture != null:
texture = content.texture
func _interact(_player: Player) -> void:
if content._apply(_player):
queue_free()

View file

@ -0,0 +1 @@
uid://v2v4keo0ydlc

View file

@ -0,0 +1,27 @@
extends BasePickupableResource
class_name WeaponPickupableResource
## Weapon that will be added on interaction
@export var weapon: PackedScene
func _apply(player: Player) -> bool:
var slot = player.weapons.first_free_slot()
# TODO: Implement proper swapping behavior when old or new weapon uses several slots
if slot == null:
slot = player.weapons.current_slot
var set_data = slot.set_weapon(weapon)
set_data.old_weapon.id = id
if slot == player.weapons.current_slot:
player.weapons.refresh_current_slot()
return update_by_id(set_data.new_weapon)
# TODO: implement proper updating
func update_by_id(new_id: StringName) -> bool:
id = new_id
return id == ""

View file

@ -0,0 +1 @@
uid://dob8q3jclxrtd

View file

@ -0,0 +1 @@
uid://fva8kqc3mk86

View file

@ -1,5 +1,7 @@
extends CharacterBody3D
class_name Player
@export var speed = 100.0
@export var fall_acceleration = 75.0
@export var vertical_sensivity = 0.005

View file

@ -27,3 +27,13 @@ func select_slot(index: int):
current_slot = slots[index]
current_weapon = current_slot.weapon
slot_selected.emit()
func first_free_slot() -> WeaponSlot:
for slot in slots:
if not slot.has_weapon:
return slot
return null
func refresh_current_slot() -> void:
var index = slots.find(current_slot)
select_slot(index)

View file

@ -5,6 +5,17 @@ class_name WeaponSlot
var has_weapon = false
var weapon: Weapon
## Contains data about swapped weapons
class WeaponSetData:
## New Weapon node, may be null
var new_weapon: Weapon
## Old weapon id, may be empty string
var old_weapon: StringName
func _init(_new_weapon: Weapon, _old_weapon: StringName):
new_weapon = _new_weapon
old_weapon = _old_weapon
func _ready():
has_weapon = get_child_count() > 0
@ -12,3 +23,20 @@ func _ready():
var child = get_child(0)
assert(child is Weapon)
weapon = child as Weapon
func set_weapon(new_weapon: PackedScene) -> WeaponSetData:
var weapon_inst = null
if new_weapon != null:
weapon_inst = new_weapon.instantiate() as Weapon
add_child(weapon_inst)
var old_weapon_id = drop_weapon()
return WeaponSetData.new(weapon_inst, old_weapon_id)
func drop_weapon() -> StringName:
var id = ""
if has_weapon:
id = weapon.id
weapon.queue_free()
_ready()
return id

View file

@ -6,6 +6,8 @@ signal fired()
signal fire_failed()
signal fire_allowed()
var id: StringName
@onready var barrel = $"Barrel"
@export var uses_hands: Array[CommandQueue.Side]