Nouvel autoload PlayerProgress qui gagne de l'XP sur: - cassage de blocs (gain variable selon le type: perle, épave, coral > sand) - collecte de perles (+25) - crafting (+10) - paliers de profondeur atteints (+20 à 10/25/50/75/100m) HUD: barre XP + label niveau en bas centre, bannière "NIVEAU X" au level-up (son bulle + fade). Popup 3D "+N XP" spawn au point d'action. Boucle court-terme dopamine: chaque action = feedback visuel immédiat. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
1.6 KiB
GDScript
68 lines
1.6 KiB
GDScript
extends Node
|
|
|
|
signal xp_gained(amount: int, source: String, world_position: Vector3)
|
|
signal xp_changed(current_xp: int, xp_for_next: int, level: int)
|
|
signal level_up(new_level: int)
|
|
|
|
const XP_BREAK_DEFAULT: int = 2
|
|
const XP_BREAK_BY_BLOCK: Dictionary = {
|
|
2: 1, # sand
|
|
3: 2, # rock
|
|
4: 5, # coral rouge
|
|
5: 5, # coral bleu
|
|
6: 1, # kelp
|
|
7: 8, # epave
|
|
8: 3, # glace
|
|
}
|
|
const XP_PEARL: int = 25
|
|
const XP_CRAFT: int = 10
|
|
const XP_ECHOLOCATE: int = 3
|
|
const XP_KILL_HOSTILE: int = 15
|
|
const XP_DEPTH_MILESTONE: int = 20
|
|
|
|
var current_xp: int = 0
|
|
var level: int = 1
|
|
|
|
var _reached_depths: Array[int] = []
|
|
|
|
|
|
func _ready() -> void:
|
|
emit_state()
|
|
|
|
|
|
func xp_for_level(lv: int) -> int:
|
|
return 50 + (lv - 1) * 40 + (lv - 1) * (lv - 1) * 10
|
|
|
|
|
|
func xp_for_next() -> int:
|
|
return xp_for_level(level)
|
|
|
|
|
|
func award(amount: int, source: String = "", world_pos: Vector3 = Vector3.ZERO) -> void:
|
|
if amount <= 0:
|
|
return
|
|
current_xp += amount
|
|
xp_gained.emit(amount, source, world_pos)
|
|
while current_xp >= xp_for_next():
|
|
current_xp -= xp_for_next()
|
|
level += 1
|
|
level_up.emit(level)
|
|
emit_state()
|
|
|
|
|
|
func award_block_break(block_id: int, world_pos: Vector3) -> void:
|
|
var gain: int = XP_BREAK_BY_BLOCK.get(block_id, XP_BREAK_DEFAULT)
|
|
award(gain, "bloc", world_pos)
|
|
|
|
|
|
func emit_state() -> void:
|
|
xp_changed.emit(current_xp, xp_for_next(), level)
|
|
|
|
|
|
func note_depth(depth_m: int) -> void:
|
|
var milestones: Array[int] = [10, 25, 50, 75, 100]
|
|
for m: int in milestones:
|
|
if depth_m >= m and not _reached_depths.has(m):
|
|
_reached_depths.append(m)
|
|
award(XP_DEPTH_MILESTONE, "profondeur %dm" % m, Vector3.ZERO)
|