use inventory_item more, have it for viewmodel specification

This commit is contained in:
veclavtalica 2025-02-13 06:51:57 +03:00
parent 1853c62699
commit c2841fbf0c
11 changed files with 74 additions and 16 deletions

13
data/coin_flower.tres Normal file
View File

@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="InventoryItem" load_steps=3 format=3 uid="uid://nrpcuqveh7io"]
[ext_resource type="Texture2D" uid="uid://cb6qv3c0iojfl" path="res://icon.svg" id="1_u477x"]
[ext_resource type="Script" path="res://src/lib/inventory_item.gd" id="3_fe16f"]
[resource]
script = ExtResource("3_fe16f")
icon = ExtResource("1_u477x")
name = "Coin Flower"
id = &"coin_flower"
stackable = false
stack_limit = 8
count = 0

View File

@ -8,3 +8,4 @@ script = ExtResource("2_inc63")
icon = ExtResource("1_2wt7x")
name = "Meat"
id = &"meat"
count = 0

13
data/water_bomb.tres Normal file
View File

@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="InventoryItem" load_steps=4 format=3 uid="uid://cmeif37pci2ek"]
[ext_resource type="Texture2D" uid="uid://cb6qv3c0iojfl" path="res://icon.svg" id="1_g8c3q"]
[ext_resource type="PackedScene" uid="uid://ba2mut58elwrh" path="res://assets/water-bomb.glb" id="2_5cxkh"]
[ext_resource type="Script" path="res://src/lib/inventory_item.gd" id="2_pe2p8"]
[resource]
script = ExtResource("2_pe2p8")
icon = ExtResource("1_g8c3q")
model = ExtResource("2_5cxkh")
name = "Water Bomb"
id = &"water_bomb"
count = 0

View File

@ -1,4 +1,5 @@
class_name Player extends CharacterBody3D
# TODO: inherit from StairStepper, not the other way around ? Probably by also having base Actor class.
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
@ -24,7 +25,7 @@ var _projectile_speed := 12.0
var _interaction_selection: Node3D
var controls_disabled := false
var held_thing: String
var held_thing: InventoryItem
# What the others see.
@ -58,7 +59,7 @@ func _physics_process(delta: float) -> void:
## Process interactivity selection.
if id == multiplayer.get_unique_id():
var collider: Object = null
if held_thing == "" and _line_of_sight.is_colliding():
if held_thing == null and _line_of_sight.is_colliding():
collider = _line_of_sight.get_collider(0)
if collider != _interaction_selection:
if _interaction_selection != null:
@ -99,15 +100,31 @@ func _physics_process(delta: float) -> void:
@rpc("any_peer", "call_local", "reliable")
func hold_thing() -> void:
held_thing = "water"
_camera_pivot.get_node("HeldViewmodel").show()
func hold_thing(p_item_instance_id: int) -> void:
var item = instance_from_id(p_item_instance_id) as InventoryItem
assert(item != null)
held_thing = item
var base_node := _camera_pivot.get_node("HeldViewmodel")
for child in base_node.get_children():
child.queue_free()
if item.model != null:
var model = item.model.instantiate()
base_node.add_child(model)
if id == multiplayer.get_unique_id():
# Disable depth test and increase render priority.
# TODO: in more complex scenarios model scene might want to have its own callback for this.
for model in base_node.get_children():
for submodel in model.get_children():
var material := submodel.mesh.surface_get_material(0).duplicate() as Material
material.render_priority += 1
material.no_depth_test = true
submodel.mesh.surface_set_material(0, material)
@rpc("any_peer", "call_local", "reliable")
func throw_thing() -> void:
held_thing = ""
_camera_pivot.get_node("HeldViewmodel").hide()
held_thing = null # TODO: represent 'empty hand' as a unique item ?
for child in _camera_pivot.get_node("HeldViewmodel").get_children():
child.queue_free()
func _unhandled_input(event: InputEvent) -> void:
@ -120,12 +137,12 @@ func _unhandled_input(event: InputEvent) -> void:
_camera_pivot.rotation.x = clamp(_camera_pivot.rotation.x, -1.2, 1.2)
return
if event.is_action_pressed("pick") and held_thing == "":
if event.is_action_pressed("pick") and held_thing == null:
if _interaction_selection != null:
_interaction_selection.get_parent().get_picked_up.rpc()
hold_thing.rpc()
hold_thing.rpc(_interaction_selection.owner.item_component.get_instance_id())
_interaction_selection.owner.get_picked_up.rpc()
if event.is_action_pressed("fire") and held_thing != "":
if event.is_action_pressed("fire") and held_thing != null:
var new_projectile: Node3D = _projectile_scene.instantiate()
_projectile_holder.add_child(new_projectile, true)
_set_projectile_authority.rpc(new_projectile.get_path(), id)

View File

@ -97,10 +97,10 @@ debug_shape_custom_color = Color(0.628721, 0, 0.256939, 1)
[node name="HeldViewmodel" type="Node3D" parent="CameraPivot"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.2, -1)
visible = false
[node name="Model" parent="CameraPivot/HeldViewmodel" instance=ExtResource("4_bfvih")]
material_override = SubResource("StandardMaterial3D_x7r08")
material_override = null
material = SubResource("StandardMaterial3D_x7r08")
[node name="ShotSound" type="AudioStreamPlayer3D" parent="."]
stream = ExtResource("3_u2hxa")

View File

@ -5,6 +5,8 @@ extends Node3D
@export var _mesh: MeshInstance3D
@export var _area: Area3D
@export var item_component: InventoryItem
var needs_water := true
var stage: int = 1
var final_stage: int = 3

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=9 format=3 uid="uid://bysgtksvovyur"]
[gd_scene load_steps=10 format=3 uid="uid://bysgtksvovyur"]
[ext_resource type="Script" path="res://src/ingame/sprout.gd" id="1_snma1"]
[ext_resource type="Resource" uid="uid://nrpcuqveh7io" path="res://data/coin_flower.tres" id="2_amjnn"]
[ext_resource type="Texture2D" uid="uid://d35y5ckne72qe" path="res://assets/sprout1.png" id="2_ipgad"]
[ext_resource type="Shader" path="res://scenes/interactivity_outline2.gdshader" id="2_oa2it"]
[ext_resource type="Texture2D" uid="uid://cwbl0r1e26eja" path="res://assets/drop.png" id="3_kghdv"]
@ -35,6 +36,7 @@ _need_water_drop = NodePath("NeedWaterDrop")
_production_timer = NodePath("ProductionTimer")
_mesh = NodePath("Mesh")
_area = NodePath("Area3D")
item_component = ExtResource("2_amjnn")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_rs2qp")

View File

@ -8,6 +8,8 @@ extends Node3D
@export var body: RigidBody3D
## no longer exists and shouldn't be considered, but not ready to be freed yet
@export var is_dead := false
## by convention is looked up in owner from areas
@export var item_component: InventoryItem
var _in_splash_range := {}

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=11 format=3 uid="uid://tdsbo3e5ic86"]
[gd_scene load_steps=12 format=3 uid="uid://tdsbo3e5ic86"]
[ext_resource type="Script" path="res://src/ingame/water_bomb.gd" id="1_lk5fq"]
[ext_resource type="AudioStream" uid="uid://dtjpv2b74g24m" path="res://assets/sfx/splash-small.wav" id="2_0wk8g"]
[ext_resource type="Resource" uid="uid://cmeif37pci2ek" path="res://data/water_bomb.tres" id="2_b3357"]
[ext_resource type="PackedScene" uid="uid://ba2mut58elwrh" path="res://assets/water-bomb.glb" id="2_v2imr"]
[ext_resource type="AudioStream" uid="uid://blgrl2wl05feq" path="res://assets/sfx/splash-small-quiet.wav" id="3_hgy7l"]
@ -57,6 +58,7 @@ _model = NodePath("Model")
_splash_particles = NodePath("SplashParticles")
_picking_area = NodePath("PickingArea")
body = NodePath("RigidBody3D")
item_component = ExtResource("2_b3357")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_0ebrr")

View File

@ -3,6 +3,8 @@ extends Resource
const INVENTORY_ITEM_DB = {
&"meat": preload("res://data/meat.tres"),
&"water_bomb": preload("res://data/water_bomb.tres"),
&"coin_flower": preload("res://data/coin_flower.tres"),
}
# keys are multiplayer ID ints, values are PlayerData

View File

@ -2,7 +2,11 @@ class_name InventoryItem
extends Resource
@export var icon: Texture2D = preload("res://icon.svg")
@export var model: PackedScene
@export var name := "NAME"
@export var id := &"ID"
@export var stackable := false
@export var stack_limit := 8
# TODO: should it be here? or context dependent, for different inventories
@export var count := 0