feat(gameplay): consommables utilisables avec touche [F]

- DolphinController expose heal/feed/refill_oxygen + signal
  use_consumable_requested (bindé sur F)
- Main.gd table CONSUMABLE_EFFECTS:
  · Bulle d'air (102): +40 O₂
  · Algue cuisinée (103): +30 faim, +5 HP
  · Amulette de soin (106): +50 HP
- Popup flottant coloré au-dessus du joueur + son bulle à l'utilisation
- HUD: hint dynamique "[F] Consommer : <item>" quand slot sélectionné = consommable

Boucle court-terme: le craft a enfin un usage direct, récompense lisible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-20 18:12:56 +00:00
parent 7f6811995d
commit 27459e1eaa
3 changed files with 100 additions and 0 deletions

View File

@@ -183,6 +183,8 @@ func _connect_dolphin_signals(dolphin: CharacterBody3D) -> void:
dolphin.echolocation_triggered.connect(_on_echolocation)
if dolphin.has_signal("hotbar_scroll"):
dolphin.hotbar_scroll.connect(inventory.scroll_hotbar)
if dolphin.has_signal("use_consumable_requested"):
dolphin.use_consumable_requested.connect(_on_use_consumable)
func _on_net_peer_connected(peer_id: int) -> void:
@@ -290,6 +292,43 @@ func _on_block_place(hit_position: Vector3, normal: Vector3) -> void:
inventory.remove_item_from_slot(inventory.selected_hotbar, 1)
const CONSUMABLE_EFFECTS: Dictionary = {
102: {"oxygen": 40.0, "hp": 0.0, "hunger": 0.0, "label": "+40 O₂", "color": Color(0.3, 0.9, 1.0)},
103: {"oxygen": 0.0, "hp": 5.0, "hunger": 30.0, "label": "+30 🍴", "color": Color(0.6, 1.0, 0.4)},
106: {"oxygen": 0.0, "hp": 50.0, "hunger": 0.0, "label": "+50 ❤", "color": Color(1.0, 0.5, 0.5)},
}
func _on_use_consumable() -> void:
if not is_instance_valid(_my_dolphin):
return
var slot: Variant = inventory.get_selected_item()
if slot == null:
return
var item_id: int = slot["item_id"]
if not CONSUMABLE_EFFECTS.has(item_id):
return
var effect: Dictionary = CONSUMABLE_EFFECTS[item_id]
if effect["oxygen"] > 0.0 and _my_dolphin.has_method("refill_oxygen"):
_my_dolphin.refill_oxygen(effect["oxygen"])
if effect["hp"] > 0.0 and _my_dolphin.has_method("heal"):
_my_dolphin.heal(effect["hp"])
if effect["hunger"] > 0.0 and _my_dolphin.has_method("feed"):
_my_dolphin.feed(effect["hunger"])
inventory.remove_item_from_slot(inventory.selected_hotbar, 1)
AudioManager.play_bubble_sfx(_my_dolphin.global_position)
_spawn_consumable_popup(effect["label"], effect["color"])
func _spawn_consumable_popup(label: String, color: Color) -> void:
if not is_instance_valid(_my_dolphin):
return
var popup_script: Script = load("res://scripts/progression/XpPopup.gd")
if popup_script == null:
return
popup_script.spawn(self, label, _my_dolphin.global_position + Vector3(0, 1.4, 0), color)
func _on_echolocation(position: Vector3, _radius: float) -> void:
AudioManager.play_bubble_sfx(position)
var am: Node = get_node_or_null("/root/AchievementManager")