extends StaticBody3D class_name BatteryBox2 @onready var ai_threat: Label3D = $AI_threat/AI_threat_label @onready var box_battery = $Battery @onready var battery_lamp_0:= $battery_lamp_0 @onready var battery_lamp_1:= $battery_lamp_1 @onready var status_lamps = [ $Status/status_0, $Status/status_1, $Status/status_2, $Status/status_3, $Status/status_4 ] @export var power_needed: int = 50 @export var max_power: int = 100 @export var display_text: String var current_power: int = 0 var battery_obj: Battery = null var blink_timer: Timer var color_dict = {25: Color(0.0, 1.697, 0.0), 50: Color(1.697, 1.697, 0.0), 75: Color(1.697, 0.85, 0.0), 100: Color(1.697, 0.0, 0.0)} signal removed_battery signal fully_charged func _ready() -> void: blink_timer = Timer.new() blink_timer.wait_time = 0.3 blink_timer.one_shot = false blink_timer.timeout.connect(_on_blink_timeout) add_child(blink_timer) ai_threat.text = tr(display_text) for lamp in status_lamps: lamp.visible = true if lamp.get_surface_override_material(0) == null: var material = StandardMaterial3D.new() lamp.set_surface_override_material(0, material) lamp.get_surface_override_material(0).albedo_color = Color.DIM_GRAY var material_b0 = battery_lamp_0.mesh.surface_get_material(0).duplicate() battery_lamp_0.mesh.surface_set_material(0, material_b0) var material_b1 = battery_lamp_1.mesh.surface_get_material(0).duplicate() battery_lamp_1.mesh.surface_set_material(0, material_b1) func insert_battery(battery: Battery) -> void: battery_obj = battery current_power = battery_obj.stored_power var lamp_color = color_dict[current_power] battery_lamp_0.mesh.surface_get_material(0).albedo_color = lamp_color battery_lamp_1.mesh.surface_get_material(0).albedo_color = lamp_color box_battery.visible = true update_status_lamps(battery_obj) func remove_battery() -> Battery: $Sprite3D.visible = false var temp_battery = battery_obj battery_obj = null if current_power == power_needed: removed_battery.emit() current_power = 0 box_battery.visible = false blink_timer.stop() for lamp in status_lamps: if lamp.get_surface_override_material(0) == null: var material = StandardMaterial3D.new() lamp.set_surface_override_material(0, material) lamp.get_surface_override_material(0).albedo_color = Color.DIM_GRAY lamp.visible = true battery_lamp_0.mesh.surface_get_material(0).albedo_color = Color.DIM_GRAY battery_lamp_1.mesh.surface_get_material(0).albedo_color = Color.DIM_GRAY temp_battery.remove_from_station() return temp_battery func update_status_lamps(battery_obj: Battery) -> void: # ratio between current_power and power_needed var ratio: float = 0.0 if power_needed != 0: ratio = float(current_power) / float(power_needed) ratio = clamp(ratio, 0.0, 1.0) # count of lamps that should be colored (0..len) var lamps_to_light: int = ceil(ratio * status_lamps.size()) # special cases: exactly full or overloaded var is_full := current_power == power_needed var is_over := current_power > power_needed if is_full: play_sounds('insert_correct') fully_charged.emit() $Sprite3D.texture = load(battery_obj.image_path) $Sprite3D.visible = true # update each lamp for i in range(lamps_to_light): var lamp = status_lamps[i] # secure that material is there if lamp.get_surface_override_material(0) == null: var material = StandardMaterial3D.new() lamp.set_surface_override_material(0, material) lamp.get_surface_override_material(0).albedo_color = Color.GREEN if is_over: play_sounds('insert_false') # too much -> all red lamp.get_surface_override_material(0).albedo_color = Color.RED lamp.visible = true elif is_full: # exaclty full -> all green lamp.get_surface_override_material(0).albedo_color = Color.GREEN lamp.visible = true else: # off / grey play_sounds('insert_false') lamp.get_surface_override_material(0).albedo_color = Color.YELLOW lamp.visible = true await get_tree().create_timer(0.3).timeout # blink if overloaded if is_over: if not blink_timer.is_stopped(): # timer is running -> nothing pass else: blink_timer.start() else: blink_timer.stop() # make sure that all are visible (if blinking before) for lamp in status_lamps: lamp.visible = true func _on_blink_timeout() -> void: # in case of too much power: lamps blink (toggle visibility) if current_power > power_needed: for lamp in status_lamps: if lamp.get_surface_override_material(0).albedo_color == Color.DIM_GRAY: lamp.get_surface_override_material(0).albedo_color = Color.RED else: lamp.get_surface_override_material(0).albedo_color = Color.DIM_GRAY func play_sounds(soundname: String) -> void: if soundname == 'insert_correct': $audio_right.play() elif soundname == 'insert_false': $audio_false.play()