You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.7 KiB
84 lines
2.7 KiB
|
3 weeks ago
|
extends PanelContainer
|
||
|
|
class_name UnitFrame
|
||
|
|
## Character portrait/unit frame displayed in top-left corner
|
||
|
|
|
||
|
|
# References
|
||
|
|
@onready var character_name: Label = $MarginContainer/VBoxContainer/NameLabel
|
||
|
|
@onready var health_bar_bg: ColorRect = $MarginContainer/VBoxContainer/HealthBarContainer/Background
|
||
|
|
@onready var health_bar_fill: ColorRect = $MarginContainer/VBoxContainer/HealthBarContainer/Background/Fill
|
||
|
|
@onready var health_text: Label = $MarginContainer/VBoxContainer/HealthBarContainer/HealthText
|
||
|
|
@onready var level_label: Label = $MarginContainer/VBoxContainer/HBoxContainer/LevelLabel
|
||
|
|
|
||
|
|
# Player reference
|
||
|
|
var player: Character = null
|
||
|
|
|
||
|
|
# Smoothing
|
||
|
|
var target_health_width: float = 0.0
|
||
|
|
var current_health_width: float = 0.0
|
||
|
|
const HEALTH_LERP_SPEED: float = 10.0
|
||
|
|
|
||
|
|
# Colors
|
||
|
|
const COLOR_HEALTH_HIGH = Color(0.0, 0.8, 0.0, 1.0) # Green (>60%)
|
||
|
|
const COLOR_HEALTH_MID = Color(1.0, 0.8, 0.0, 1.0) # Yellow (30-60%)
|
||
|
|
const COLOR_HEALTH_LOW = Color(0.8, 0.0, 0.0, 1.0) # Red (<30%)
|
||
|
|
|
||
|
|
func _ready():
|
||
|
|
# Initialize
|
||
|
|
if health_bar_fill:
|
||
|
|
current_health_width = health_bar_fill.size.x
|
||
|
|
target_health_width = health_bar_fill.size.x
|
||
|
|
|
||
|
|
print("[UnitFrame] Unit frame initialized")
|
||
|
|
|
||
|
|
func _process(delta):
|
||
|
|
# Smooth health bar animation
|
||
|
|
if health_bar_fill and abs(current_health_width - target_health_width) > 0.1:
|
||
|
|
current_health_width = lerp(current_health_width, target_health_width, HEALTH_LERP_SPEED * delta)
|
||
|
|
health_bar_fill.size.x = current_health_width
|
||
|
|
|
||
|
|
## Set player reference and display info
|
||
|
|
func set_player(p: Character):
|
||
|
|
player = p
|
||
|
|
if not player:
|
||
|
|
return
|
||
|
|
|
||
|
|
# Get player name from Network
|
||
|
|
var player_id = player.name.to_int() # Player nodes are named with their peer_id
|
||
|
|
if Network.players.has(player_id):
|
||
|
|
var player_data = Network.players[player_id]
|
||
|
|
if character_name:
|
||
|
|
character_name.text = player_data["nick"]
|
||
|
|
else:
|
||
|
|
if character_name:
|
||
|
|
character_name.text = "Player"
|
||
|
|
|
||
|
|
# Set level (hardcoded for now)
|
||
|
|
if level_label:
|
||
|
|
level_label.text = "Lv 1"
|
||
|
|
|
||
|
|
# Update health
|
||
|
|
update_health(player.current_health, player.max_health)
|
||
|
|
|
||
|
|
## Update health bar
|
||
|
|
func update_health(current: float, maximum: float):
|
||
|
|
if not health_bar_fill or not health_bar_bg or not health_text:
|
||
|
|
return
|
||
|
|
|
||
|
|
var health_percent = current / maximum if maximum > 0 else 0.0
|
||
|
|
health_percent = clamp(health_percent, 0.0, 1.0)
|
||
|
|
|
||
|
|
# Update fill width
|
||
|
|
var max_width = health_bar_bg.size.x
|
||
|
|
target_health_width = max_width * health_percent
|
||
|
|
|
||
|
|
# Update color based on health percentage
|
||
|
|
if health_percent > 0.6:
|
||
|
|
health_bar_fill.color = COLOR_HEALTH_HIGH
|
||
|
|
elif health_percent > 0.3:
|
||
|
|
health_bar_fill.color = COLOR_HEALTH_MID
|
||
|
|
else:
|
||
|
|
health_bar_fill.color = COLOR_HEALTH_LOW
|
||
|
|
|
||
|
|
# Update text
|
||
|
|
health_text.text = "%d / %d" % [int(current), int(maximum)]
|