From 211ef3bbc773013e09b40d7fbbebbfcebb113054 Mon Sep 17 00:00:00 2001 From: wanp Date: Wed, 12 Feb 2025 14:41:03 -0300 Subject: [PATCH] start work on inventory, items, coins --- data/meat.tres | 10 +++++++ src/ingame/ingame.gd | 6 ++++ src/ingame/ingame.tscn | 12 +++++++- src/ingame/player.gd | 2 +- src/ingame/water_bomb.gd | 4 +-- src/lib/game_state.gd | 8 +++++ src/lib/{item.gd => inventory_item.gd} | 4 ++- src/main/main.gd | 41 ++++++++++++++++++++++++++ 8 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 data/meat.tres rename src/lib/{item.gd => inventory_item.gd} (71%) diff --git a/data/meat.tres b/data/meat.tres new file mode 100644 index 0000000..e9ffa86 --- /dev/null +++ b/data/meat.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="InventoryItem" load_steps=3 format=3 uid="uid://cbbclpp04ptlf"] + +[ext_resource type="Texture2D" uid="uid://cb6qv3c0iojfl" path="res://icon.svg" id="1_2wt7x"] +[ext_resource type="Script" path="res://src/lib/inventory_item.gd" id="2_inc63"] + +[resource] +script = ExtResource("2_inc63") +icon = ExtResource("1_2wt7x") +name = "Meat" +id = &"meat" diff --git a/src/ingame/ingame.gd b/src/ingame/ingame.gd index 17b3ee8..89d7f29 100644 --- a/src/ingame/ingame.gd +++ b/src/ingame/ingame.gd @@ -11,6 +11,7 @@ extends Node3D @export var _chat_panel_inactive: Panel @export var _chat_history_inactive: VBoxContainer @export var _chat_history_scroll_inactive: ScrollContainer +@export var _coin_label: RichTextLabel ## Things to yet play, so to not repeat ourselves much. const PLAYLIST: Array[String] = [ @@ -83,6 +84,11 @@ func _input(event: InputEvent) -> void: _deactivate_chat() +func _process(_delta: float) -> void: + # this is fine but should this be done in response to a signal instead? + _coin_label.text = "COINS: %d" % GameState.fetch().coins + + func _activate_chat() -> void: _chat_panel.show() _chat_panel_inactive.hide() diff --git a/src/ingame/ingame.tscn b/src/ingame/ingame.tscn index 07ace52..8b33adc 100644 --- a/src/ingame/ingame.tscn +++ b/src/ingame/ingame.tscn @@ -32,7 +32,7 @@ sky = SubResource("Sky_ygvd3") ambient_light_color = Color(0, 0.164706, 0.278431, 1) ambient_light_energy = 2.0 -[node name="Ingame" type="Node3D" node_paths=PackedStringArray("_soundtrack", "_players", "_chat_panel", "_chat_input", "_chat_history_scroll", "_chat_history", "_chat_panel_inactive", "_chat_history_inactive", "_chat_history_scroll_inactive")] +[node name="Ingame" type="Node3D" node_paths=PackedStringArray("_soundtrack", "_players", "_chat_panel", "_chat_input", "_chat_history_scroll", "_chat_history", "_chat_panel_inactive", "_chat_history_inactive", "_chat_history_scroll_inactive", "_coin_label")] script = ExtResource("1_akuuj") _player_scene = ExtResource("2_w1gjc") _soundtrack = NodePath("Soundtrack") @@ -44,6 +44,7 @@ _chat_history = NodePath("UI/ChatPanel/ChatHistoryScroll/ChatHistory") _chat_panel_inactive = NodePath("UI/ChatPanelInactive") _chat_history_inactive = NodePath("UI/ChatPanelInactive/ChatHistoryScroll/ChatHistory") _chat_history_scroll_inactive = NodePath("UI/ChatPanelInactive/ChatHistoryScroll") +_coin_label = NodePath("UI/CoinLabel") [node name="Soundtrack" type="AudioStreamPlayer" parent="."] bus = &"Music" @@ -165,6 +166,15 @@ text = "+5!" wait_time = 3.0 one_shot = true +[node name="CoinLabel" type="RichTextLabel" parent="UI"] +clip_contents = false +offset_left = 16.0 +offset_top = 16.0 +offset_right = 192.0 +offset_bottom = 40.0 +theme_override_constants/outline_size = 6 +text = "Coins: 0" + [node name="CSGBox3D" type="CSGBox3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7.45058e-09, 0) collision_mask = 0 diff --git a/src/ingame/player.gd b/src/ingame/player.gd index a552e29..90bb608 100644 --- a/src/ingame/player.gd +++ b/src/ingame/player.gd @@ -25,7 +25,7 @@ var _interaction_selection: Node3D var controls_disabled := false var held_thing: String - + # What the others see. func _init_bystander() -> void: diff --git a/src/ingame/water_bomb.gd b/src/ingame/water_bomb.gd index 27d6b0d..a8d982d 100644 --- a/src/ingame/water_bomb.gd +++ b/src/ingame/water_bomb.gd @@ -80,8 +80,8 @@ func get_picked_up() -> void: func mark_interactive() -> void: - ($Model as CSGSphere3D).material_override.next_pass.set("shader_parameter/color", Color.WHITE) + (_model as CSGSphere3D).material_override.next_pass.set("shader_parameter/color", Color.WHITE) func mark_non_interactive() -> void: - ($Model as CSGSphere3D).material_override.next_pass.set("shader_parameter/color", Color(1, 1, 1, 0)) + (_model as CSGSphere3D).material_override.next_pass.set("shader_parameter/color", Color(1, 1, 1, 0)) diff --git a/src/lib/game_state.gd b/src/lib/game_state.gd index 0529cab..d2d62df 100644 --- a/src/lib/game_state.gd +++ b/src/lib/game_state.gd @@ -1,7 +1,15 @@ class_name GameState extends Resource +const INVENTORY_ITEM_DB = { + &"meat": preload("res://data/meat.tres"), +} + +# keys are multiplayer ID ints, values are PlayerData @export var player_data := {} +# keys are InventoryItem resource IDs (from db), values are InventoryItems +@export var inventory := {} +@export var coins: int static var _instance := GameState.new() diff --git a/src/lib/item.gd b/src/lib/inventory_item.gd similarity index 71% rename from src/lib/item.gd rename to src/lib/inventory_item.gd index da56a34..d80f670 100644 --- a/src/lib/item.gd +++ b/src/lib/inventory_item.gd @@ -1,6 +1,8 @@ -class_name Item +class_name InventoryItem extends Resource @export var icon: Texture2D = preload("res://icon.svg") @export var name := "NAME" @export var id := &"ID" + +@export var count := 0 diff --git a/src/main/main.gd b/src/main/main.gd index d01cde3..2a57524 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -35,6 +35,11 @@ func _on_player_joined(id: int) -> void: _register_player.rpc_id(id, username) if _game_started: + set_coins.rpc_id(id, GameState.fetch().coins) + + for item_id in GameState.fetch().inventory: + set_inventory_item_count.rpc_id(id, item_id, GameState.fetch().inventory[item_id].count) + _start_game.rpc_id(id) @@ -173,3 +178,39 @@ func _on_chat_message_submitted(text := "") -> void: _submit_chat_message.rpc_id(1, _chat_input.text) _chat_input.clear() + + +@rpc("authority", "call_local", "reliable") +func set_coins(value: int) -> void: + GameState.fetch().coins = value + + +@rpc("authority", "call_local", "reliable") +func add_inventory_item(item_id: StringName, amount: int) -> void: + if not GameState.fetch().inventory.has(item_id): + GameState.fetch().inventory[item_id] = GameState.INVENTORY_ITEM_DB[item_id].duplicate() + + GameState.fetch().inventory[item_id].count += amount + + +@rpc("authority", "call_local", "reliable") +func remove_inventory_item(item_id: StringName, amount: int) -> void: + assert(GameState.fetch().inventory.has(item_id)) + + GameState.fetch().inventory[item_id].count -= amount + assert(GameState.fetch().inventory[item_id].count >= 0) + + if GameState.fetch().inventory[item_id].count == 0: + GameState.fetch().inventory.erase(item_id) + + +@rpc("authority", "call_local", "reliable") +func set_inventory_item_count(item_id: StringName, value: int) -> void: + assert(value >= 0) + if not GameState.fetch().inventory.has(item_id): + GameState.fetch().inventory[item_id] = GameState.INVENTORY_ITEM_DB[item_id].duplicate() + + GameState.fetch().inventory[item_id].count = value + + if GameState.fetch().inventory[item_id].count == 0: + GameState.fetch().inventory.erase(item_id)