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)