diff --git a/scenes/item_generator.tscn b/scenes/item_generator.tscn index 83c581c..b20d531 100644 --- a/scenes/item_generator.tscn +++ b/scenes/item_generator.tscn @@ -1,13 +1,17 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=8 format=2] [ext_resource path="res://scenes/coin_machine.tscn" type="PackedScene" id=1] [ext_resource path="res://scenes/item_holder.tscn" type="PackedScene" id=2] -[ext_resource path="res://scripts/item_generator.gd" type="Script" id=3] +[ext_resource path="res://scripts/item_generator/item_generator.gd" type="Script" id=3] +[ext_resource path="res://scenes/item_dump.tscn" type="PackedScene" id=4] +[ext_resource path="res://scenes/status_light.tscn" type="PackedScene" id=5] +[ext_resource path="res://item_types/repair_kit.tres" type="Resource" id=6] [sub_resource type="CylinderMesh" id=1] [node name="item_generator" type="Spatial"] script = ExtResource( 3 ) +start_broken = true [node name="MeshInstance" type="MeshInstance" parent="."] mesh = SubResource( 1 ) @@ -31,5 +35,15 @@ unique_name_in_owner = true unique_name_in_owner = true one_shot = true +[node name="item_dump" parent="." instance=ExtResource( 4 )] +unique_name_in_owner = true +item_type_0 = ExtResource( 6 ) +item_count_0 = 1 + +[node name="status_light" parent="." instance=ExtResource( 5 )] +unique_name_in_owner = true +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.13718 ) + [connection signal="coin_requirement_met" from="coin_machine" to="." method="_on_coin_machine_coin_requirement_met"] [connection signal="timeout" from="gen_timer" to="." method="_on_gen_timer_timeout"] +[connection signal="item_dump_completed" from="item_dump" to="." method="_on_item_dump_item_dump_completed"] diff --git a/scripts/crafting_station/crafting_station.gd b/scripts/crafting_station/crafting_station.gd index 776b0cc..a86e60b 100644 --- a/scripts/crafting_station/crafting_station.gd +++ b/scripts/crafting_station/crafting_station.gd @@ -69,5 +69,4 @@ func _on_item_dump_item_dump_completed(): func take_damage(damage : int = 1): .take_damage(damage) - if state != null: - state.on_damage_taken() + state.on_damage_taken() diff --git a/scripts/crafting_station/state/working.gd b/scripts/crafting_station/state/working.gd index 95c0da6..bcdd024 100644 --- a/scripts/crafting_station/state/working.gd +++ b/scripts/crafting_station/state/working.gd @@ -50,4 +50,5 @@ func on_item_holder_item_changed(item): func on_damage_taken(): if ctx.current_hp <= 0: + ctx.gen_timer.stop() ctx.change_state(ctx.States[ctx.EState.BROKEN].new()) diff --git a/scripts/item_generator.gd b/scripts/item_generator.gd deleted file mode 100644 index 5914dbe..0000000 --- a/scripts/item_generator.gd +++ /dev/null @@ -1,66 +0,0 @@ -extends Spatial - -export var gen_item : Resource -export var gen_time : float = 5.0 -export var gen_count : int = 2 - -var item_slots - -func _ready(): - assert(gen_item != null) - item_slots = get_tree().get_nodes_in_group("conveyor_item_slots") - assert(item_slots != null) - for item_slot in item_slots: - item_slot.connect("item_changed", self, "_on_item_slot_item_changed") - update_coin_machine_status() - $"%gen_timer".one_shot = true - $"%progress_text".visible = false - -func update_progress_viz(): - if not $"%progress_text".visible: - return - var time_left : float = $"%gen_timer".time_left - var time_passed : float = gen_time - time_left - var percent_complete : float = (time_passed / gen_time) * 100.0 - $"%progress_text".text = "Progress: %d%%" % percent_complete - -func _process(delta): - update_progress_viz() - -func is_generating() -> bool: - return $"%gen_timer".time_left > 0 - -func start_generation(): - $"%progress_text".visible = true - $"%gen_timer".start(gen_time) - update_coin_machine_status() - for item_slot in item_slots: - item_slot.add_enabled = false - -func _on_coin_machine_coin_requirement_met(player): - assert(is_generator_ready()) - start_generation() - -func is_generator_ready(): - for item_slot in item_slots: - if item_slot.has_item(): - return false - return not is_generating() - -func update_coin_machine_status(): - $"%coin_machine".enabled = is_generator_ready() - -#Note(asr): dynamically connect item_changed signal -#on all nodes in the "item_slots" group. See _ready() -func _on_item_slot_item_changed(item): - update_coin_machine_status() - -func _on_gen_timer_timeout(): - var count : int = 0 - for item_slot in item_slots: - if count < gen_count: - item_slot.spawn_item(gen_item) - count += 1 - item_slot.add_enabled = true - update_coin_machine_status() - $"%progress_text".visible = false diff --git a/scripts/item_generator/item_generator.gd b/scripts/item_generator/item_generator.gd new file mode 100644 index 0000000..6b87875 --- /dev/null +++ b/scripts/item_generator/item_generator.gd @@ -0,0 +1,65 @@ +extends Damageable + +enum EState {IDLE, WORKING, BLOCKED, BROKEN, NUM_STATES} + +const States = { +EState.IDLE : preload("res://scripts/item_generator/state/idle.gd"), +EState.WORKING : preload("res://scripts/item_generator/state/working.gd"), +EState.BLOCKED : preload("res://scripts/item_generator/state/blocked.gd"), +EState.BROKEN : preload("res://scripts/item_generator/state/broken.gd") +} + +export var gen_item : Resource +export var gen_time : float = 5.0 +export var gen_count : int = 2 + +onready var coin_machine = $"%coin_machine" +onready var gen_timer = $"%gen_timer" +onready var item_dump = $"%item_dump" +onready var status_light = $"%status_light" +onready var progress_text = $"%progress_text" + +var state = null +var item_slots + +func _ready(): + assert(gen_item != null) + item_slots = get_tree().get_nodes_in_group("conveyor_item_slots") + assert(item_slots != null) + for item_slot in item_slots: + item_slot.connect("item_changed", self, "_on_item_slot_item_changed") + gen_timer.wait_time = gen_time + gen_timer.one_shot = true + + state = States[EState.BROKEN].new() if start_broken else States[EState.IDLE].new() + state.ctx = self + state.enter_from(null) + print("item_generator: NULL -> ", state.NAME) + +func _process(delta): + state.update(delta) + +func change_state(new_state): + print("crafting_station: ", state.NAME, " -> ", new_state.NAME) + new_state.ctx = self + state.exit_to(new_state) + new_state.enter_from(state) + state = new_state + +func _on_coin_machine_coin_requirement_met(player): + state.on_coin_machine_coin_requirement_met(player) + +func _on_gen_timer_timeout(): + state.on_gen_timer_timeout() + +#Note(asr): dynamically connect item_changed signal +#on all nodes in the "item_slots" group. See _ready() +func _on_item_slot_item_changed(item): + state.on_item_slot_item_changed(item) + +func _on_item_dump_item_dump_completed(): + state.on_item_dump_item_dump_completed() + +func take_damage(damage : int = 1): + .take_damage(damage) + state.on_damage_taken() diff --git a/scripts/item_generator/state/blocked.gd b/scripts/item_generator/state/blocked.gd new file mode 100644 index 0000000..076a02d --- /dev/null +++ b/scripts/item_generator/state/blocked.gd @@ -0,0 +1,43 @@ +extends Reference + +const NAME = "blocked" + +var ctx = null +var label : String = "Blocked!" + +func _init(var block_string : String): + label = block_string + +func enter_from(state): + for item_slot in ctx.item_slots: + item_slot.add_enabled = true + item_slot.remove_enabled = true + ctx.item_dump.enabled = false + ctx.coin_machine.enabled = false + ctx.progress_text.text = label + ctx.status_light.warn() + +func exit_to(state): + pass + +func update(delta): + pass + +func on_coin_machine_coin_requirement_met(player): + assert(false, "coin machine should be disabled while blocked") + +func on_gen_timer_timeout(): + assert(false, "gen timer should be disabled while blocked") + +func on_item_slot_item_changed(item): + for item_slot in ctx.item_slots: + if item_slot.has_item(): + return + ctx.change_state(ctx.States[ctx.EState.IDLE].new()) + +func on_item_dump_item_dump_completed(): + assert(false, "item dump should be disabled while blocked") + +func on_damage_taken(): + if ctx.current_hp <= 0: + ctx.change_state(ctx.States[ctx.EState.BROKEN].new()) diff --git a/scripts/item_generator/state/broken.gd b/scripts/item_generator/state/broken.gd new file mode 100644 index 0000000..c15dc20 --- /dev/null +++ b/scripts/item_generator/state/broken.gd @@ -0,0 +1,43 @@ +extends Reference + +const NAME = "broken" + +var ctx = null + +func _init(): + pass + +func enter_from(state): + for item_slot in ctx.item_slots: + item_slot.add_enabled = true + item_slot.remove_enabled = true + ctx.item_dump.enabled = true + ctx.item_dump.reset() + ctx.coin_machine.enabled = false + ctx.progress_text.text = "Broken!" + ctx.status_light.fail() + +func exit_to(state): + pass + +func update(delta): + pass + +func on_coin_machine_coin_requirement_met(player): + assert(false, "coin machine should be disabled while broken") + +func on_gen_timer_timeout(): + assert(false, "gen timer should be disabled while broken") + +func on_item_slot_item_changed(item): + assert(false, "item dump should be disabled while broken") + +func on_item_dump_item_dump_completed(): + for item_slot in ctx.item_slots: + if item_slot.has_item(): + ctx.change_state(ctx.States[ctx.EState.BLOCKED].new("Blocked!")) + return + ctx.change_state(ctx.States[ctx.EState.IDLE].new()) + +func on_damage_taken(): + assert(false, "cant take damage if already broken") diff --git a/scripts/item_generator/state/idle.gd b/scripts/item_generator/state/idle.gd new file mode 100644 index 0000000..22ff067 --- /dev/null +++ b/scripts/item_generator/state/idle.gd @@ -0,0 +1,41 @@ +extends Reference + +const NAME = "idle" + +var ctx = null +var item_to_craft = null + +func _init(): + pass + +func enter_from(state): + for item_slot in ctx.item_slots: + item_slot.add_enabled = true + item_slot.remove_enabled = true + ctx.item_dump.enabled = false + ctx.coin_machine.enabled = true + ctx.progress_text.text = "Ready!" + ctx.status_light.idle() + +func exit_to(state): + pass + +func update(delta): + pass + +func on_coin_machine_coin_requirement_met(player): + ctx.change_state(ctx.States[ctx.EState.WORKING].new()) + +func on_gen_timer_timeout(): + assert(false, "gen timer cannot be running while idle") + +func on_item_slot_item_changed(item): + if item != null: + ctx.change_state(ctx.States[ctx.EState.BLOCKED].new("Blocked!")) + +func on_item_dump_item_dump_completed(): + assert(false, "item dump should be disabled while idle") + +func on_damage_taken(): + if ctx.current_hp <= 0: + ctx.change_state(ctx.States[ctx.EState.BROKEN].new()) diff --git a/scripts/item_generator/state/working.gd b/scripts/item_generator/state/working.gd new file mode 100644 index 0000000..8d6ed9b --- /dev/null +++ b/scripts/item_generator/state/working.gd @@ -0,0 +1,50 @@ +extends Reference + +const NAME = "working" + +var ctx = null + +func _init(): + pass + +func enter_from(state): + for item_slot in ctx.item_slots: + item_slot.add_enabled = false + item_slot.remove_enabled = false + ctx.item_dump.enabled = false + ctx.coin_machine.enabled = false + ctx.progress_text.text = "Progress: 0%" + ctx.status_light.activate() + ctx.gen_timer.start() + +func exit_to(state): + pass + +func update(delta): + var time_left : float = ctx.gen_timer.time_left + var time_passed : float = ctx.gen_time - time_left + var percent_complete : float = (time_passed / ctx.gen_time) * 100.0 + ctx.progress_text.text = "Progress: %d%%" % percent_complete + +func on_coin_machine_coin_requirement_met(player): + assert(false, "coin machine should be disabled while working") + +func on_gen_timer_timeout(): + var count : int = 0 + for item_slot in ctx.item_slots: + if count < ctx.gen_count: + item_slot.spawn_item(ctx.gen_item) + count += 1 + item_slot.add_enabled = true + ctx.change_state(ctx.States[ctx.EState.BLOCKED].new("Finished!")) + +func on_item_slot_item_changed(item): + assert(item != null) + +func on_item_dump_item_dump_completed(): + assert(false, "item dump should be disabled while working") + +func on_damage_taken(): + if ctx.current_hp <= 0: + ctx.gen_timer.stop() + ctx.change_state(ctx.States[ctx.EState.BROKEN].new())