extends Node func _ready() -> void: EventBus.boss_defeated.connect(_on_boss) func _on_boss(boss: Node) -> void: if not (multiplayer.is_server() or multiplayer.multiplayer_peer == null): return var amount: float = float(Stats.get_stat(boss, "xp_value", 100.0)) if GameState.dungeon_red: amount *= 5.0 for player in get_tree().get_nodes_in_group("player"): award(player, amount) func award_for_enemy(enemy: Node) -> void: if not (multiplayer.is_server() or multiplayer.multiplayer_peer == null): return var amount: float = float(Stats.get_stat(enemy, "xp_value", 5.0)) for player in get_tree().get_nodes_in_group("player"): var d: float = (player as Node3D).global_position.distance_to((enemy as Node3D).global_position) if d <= 50.0: award(player, amount) func award(player: Node, amount: float) -> void: if not Stats.has(player): return var xp: float = float(Stats.get_stat(player, "xp", 0.0)) + amount var to_next: float = float(Stats.get_stat(player, "xp_to_next", 50.0)) var level: int = int(Stats.get_stat(player, "level", 1)) while xp >= to_next: xp -= to_next level += 1 to_next = round(to_next * 1.6) _level_up(player, level) Stats.set_stat(player, "xp", xp) Stats.set_stat(player, "xp_to_next", to_next) Stats.set_stat(player, "level", level) EventBus.xp_gained.emit(player, amount) func _level_up(player: Node, new_level: int) -> void: for stat in [&"max_health", &"max_shield", &"speed"]: var cur: float = float(Stats.get_stat(player, stat, 0.0)) Stats.set_stat(player, stat, cur * 1.4) Stats.set_stat(player, "health", Stats.get_stat(player, "max_health")) Stats.set_stat(player, "shield", Stats.get_stat(player, "max_shield")) EventBus.level_up.emit(player, new_level) EventBus.health_changed.emit(player, Stats.get_stat(player, "health"), Stats.get_stat(player, "max_health")) EventBus.shield_changed.emit(player, Stats.get_stat(player, "shield"), Stats.get_stat(player, "max_shield"))