extends PanelContainer @onready var printer_name_label: Label = $MarginContainer/MainArea/TopInfo/PrinterLabel @onready var printer_model_label: Label = $MarginContainer/MainArea/Model/PrinterModelLabel @onready var progress_bar: ProgressBar = $MarginContainer/MainArea/PrintInfo/ProgressBar @onready var select_job: OptionButton = $MarginContainer/MainArea/SelectJob @onready var select_filament: OptionButton = $MarginContainer/MainArea/SelectFilament @onready var status_label: RichTextLabel = $MarginContainer/MainArea/TopInfo/StatusLabel @onready var time_left_label: RichTextLabel = $MarginContainer/MainArea/PrintInfo/InfoRow2/TimeLeftLabel @onready var start_button: Button = $MarginContainer/MainArea/Buttons/StartButton @onready var reward_label: RichTextLabel = $MarginContainer/MainArea/PrintInfo/InfoRow2/RewardLabel @onready var quality_label: RichTextLabel = $MarginContainer/MainArea/PrintInfo/InfoRow1/QualityLabel @onready var loaded_filament_label: RichTextLabel = $MarginContainer/MainArea/PrintInfo/InfoRow1/LoadedFilament var printer_data: PrinterData # - Job and Filament selection variables var selected_job: JobData var selected_job_index: int var selected_filament: Node = null var selected_filament_index: int # - Printer states var is_printing: bool = false var print_failed: bool = false # Variables - Failure calculations var time_left: float var failure_points: Array var failure_point_amount: float = 5 var print_quality: float = 1.0 func _ready() -> void: GameData.refresh_printer_dropdown.connect(_on_refresh_printer_dropdown) func initialize_printer(data: PrinterData) -> void: printer_data = data printer_name_label.text = printer_data.printer_manufacturer printer_model_label.text = printer_data.printer_type quality_label.visible = false reward_label.visible = false time_left_label.visible = false loaded_filament_label.visible = true time_left = 0 status_label.text = 'Status: [color=%s]%s[/color]' % [GameData.hex_white, "Free"] progress_bar.visible = false progress_bar.value = 0 GameData.display_msg('%s printer bought!' % printer_data.printer_manufacturer, GameData.hex_green) _on_select_job_pressed() _on_select_filament_pressed() func _process(delta) -> void: if is_printing: select_job.hide() select_filament.hide() progress_bar.show() time_left_label.show() quality_label.show() reward_label.show() set_status() var text_color = GameData.hex_green if print_quality < 1.0: text_color = GameData.hex_red quality_label.text = 'Quality: [color=%s]%.0f%%[/color]' % [text_color, (print_quality * 100)] reward_label.text = 'Reward: [color=%s]%.2f €[/color]' % [text_color, (selected_job.job_reward * print_quality)] var total_time = selected_job.job_time / printer_data.printer_speed var progress = (total_time - time_left) / total_time selected_filament.amount -= 0.5 * delta time_left -= delta progress_bar.value = progress time_left_label.text = 'Time left: [color=%s]%s[/color]' % [GameData.hex_blue, calculate_time_left(time_left)] if time_left <= 0: var end_reward = selected_job.job_reward * print_quality var end_xp = selected_job.job_experience * print_quality PlayerData.give_money.emit(end_reward) PlayerData.give_experience.emit(end_xp) GameData.display_msg('Print completed! Got %.2f €' % end_reward, GameData.hex_green) reset_status() # Old print failure condition - 1st Fail, 2nd + 3rd Quality decrease #if failure_points.has(roundf(progress_bar.value * 100)): #if failure_points[0] == roundf(progress_bar.value * 100): #if check_failure(roundf(progress_bar.value * 100)): #print_failed = true #reset_status() #elif check_failure(roundf(progress_bar.value * 100)): #print_quality -= 0.1 # New print failure condition - Only quality decrease if failure_points.has(roundf(progress_bar.value * 100)): if check_failure(roundf(progress_bar.value * 100)): print_quality -= 0.1 func reset_status() -> void: is_printing = false set_status() print_failed = false print_quality = 1.0 failure_points = [] time_left_label.hide() quality_label.hide() reward_label.hide() progress_bar.hide() progress_bar.value = 0 time_left = 0 select_filament.show() select_job.disabled = false select_job.show() start_button.disabled = false _on_select_job_pressed() func set_status() -> void: var color_hex: String = GameData.hex_white var status: String if print_failed: status = 'Failed' color_hex = GameData.hex_red GameData.display_msg('Print failed!',color_hex) elif is_printing: status = 'Printing' color_hex = GameData.hex_blue else: status = 'Free' color_hex = GameData.hex_green status_label.text = 'Status: [color=%s]%s[/color]' % [color_hex, status] func calculate_fail_thresholds() -> Array: var failure_checkpoints: Array = [] var failure_range = roundf(100.0 / failure_point_amount) for point in failure_point_amount: var range_min = failure_checkpoints.size() * (failure_range + 1) var range_max = failure_checkpoints.size() * (failure_range + 1) + failure_range failure_checkpoints.append(roundf(randf_range(\ range_min, range_max))) print('Failure points: ', failure_checkpoints) return failure_checkpoints func check_failure(value: float) -> bool: if randf() >= PlayerData.failure_chance: failure_points[failure_points.bsearch(value, true)] = 0 return false else: failure_points[failure_points.bsearch(value, true)] = 0 return true func calculate_time_left(time) -> String: var minutes: int = 0 if time >= 60: while time >= 60: minutes += 1 time -= 60 return '%d m %.2f s' % [minutes, time] else: return '%.2f s' % time func _on_refresh_printer_dropdown() -> void: if is_printing: return _on_select_job_pressed() func _on_sell_button_pressed() -> void: PlayerData.give_money.emit(printer_data.printer_price * PlayerData.sell_multiplier) PlayerData.owned_printers -= 1 queue_free() func _on_select_filament_pressed() -> void: select_filament.clear() var current_filaments = GameData.inventory.get_children() if current_filaments.is_empty(): select_filament.add_item("Out of filament") loaded_filament_label.text = 'Loaded filament: None' selected_filament = null else: for filament in current_filaments: var data = filament.filament_data var amount = filament.amount var item_text = '%s | %.2f g' % [data.material, amount] select_filament.add_item(item_text) var current_index = select_filament.item_count - 1 select_filament.set_item_metadata(current_index, filament) selected_filament = select_filament.get_item_metadata(0) selected_job_index = 0 selected_filament.amount_changed.connect(_on_filament_amount_changed) _on_filament_amount_changed(selected_filament.amount) func _on_select_filament_item_selected(index: int) -> void: selected_filament = select_filament.get_item_metadata(index) selected_filament_index = index selected_filament.amount_changed.connect(_on_filament_amount_changed) _on_filament_amount_changed(selected_filament.amount) func _on_select_job_pressed() -> void: select_job.clear() if PlayerData.jobs.is_empty(): select_job.add_item("No jobs accepted") start_button.disabled = true else: start_button.disabled = false for job in PlayerData.jobs: var item_text = '%s (XP: %.2f | %.2f € | %s)' %\ [job.job_name, job.job_experience, job.job_reward, calculate_time_left(job.job_time / printer_data.printer_speed)] select_job.add_item(item_text) var current_index = select_job.item_count - 1 select_job.set_item_metadata(current_index, job) selected_job = select_job.get_item_metadata(0) selected_job_index = 0 func _on_select_job_item_selected(index: int) -> void: selected_job = select_job.get_item_metadata(index) selected_job_index = index func _on_filament_amount_changed(new_amount: float) -> void: loaded_filament_label.text = 'Loaded filament: [color=%s]%s | %.2f g[/color]' % [GameData.hex_blue, selected_filament.filament_data.material, new_amount] func _on_start_button_pressed() -> void: if select_job.get_item_text(0) == "No jobs accepted": return if select_filament.get_item_text(0) == "Out of filament": return time_left = selected_job.job_time / printer_data.printer_speed progress_bar.value = 0 start_button.disabled = true is_printing = true # Remove job from job selection dropdown if PlayerData.jobs.size() == 1: PlayerData.jobs.clear() else: PlayerData.jobs.remove_at(selected_job_index) failure_points = calculate_fail_thresholds() GameData.refresh_printer_dropdown.emit()