diff --git a/README.md b/README.md index 950d4c8..c955253 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ -# LD39 Game +# Dead in the Water - LD39 Game A game produced for [Ludum Dare 39](http://ldjam.com/events/ludum-dare/39) with the theme "Running out of Power" +Your ship has been badly damaged and the reactor is broken. You must repair your reactor before you run +out of energy. Failure to do so will leave you dead, drifting throughout space of aeons to come. + # LICENSE Source assets (under the directory source\_assets/) are licensed under CC-BY-SA 4.0, see source\_assets/LICENSE.txt for the complete wording. diff --git a/game/areas/area_base.gd b/game/areas/area_base.gd new file mode 100644 index 0000000..0ed41db --- /dev/null +++ b/game/areas/area_base.gd @@ -0,0 +1,61 @@ +extends Node2D + +signal game_area_activation_changed +signal game_area_health_changed +signal game_area_clicked + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" +export(int) var max_health = 3 +export(int) var health = 3 +export(bool) var activated = false +export(int) var energy_cost = 0 +export(String) var display_name = '' +var loot_table = {} + +func set_health(health): + if health > self.max_health: + health = self.max_health + if (health == self.health): + return + var old_health = self.health + self.health = health + if self.health < 0: + self.health = 0 + if self.health == 0: + get_node('CheckButton').set_disabled(true) + if self.health > 0: + get_node('CheckButton').set_disabled(false) + emit_signal('game_area_health_changed', old_health, health, self.max_health) + +func set_activate(activate): + if self.activated == activate: + return + self.activated = activate + emit_signal('game_area_activation_changed', self, activate) + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + get_node('Label').set_text('Cost: %d energy' % self.energy_cost) + get_node('display_name').set_text(self.display_name) + emit_signal('game_area_health_changed', self.health, self.health, self.max_health) + if self.health <= 0: + get_node('CheckButton').set_disabled(true) + emit_signal('game_area_activation_changed', self, self.activated) + + +func _on_Area2D_input_event(viewport, event, shape_idx): + if event.type == InputEvent.MOUSE_BUTTON && event.button_index == BUTTON_LEFT && event.pressed: + emit_signal('game_area_clicked', self) + + +func _on_CheckButton_toggled( pressed ): + self.set_activate(pressed) + +func set_hilight(x): + if x: + get_node('Sprite').set_modulate(Color(0, 1, 0, 1)) + else: + get_node('Sprite').set_modulate(Color(1, 1, 1, 1)) \ No newline at end of file diff --git a/game/areas/area_base.tscn b/game/areas/area_base.tscn new file mode 100644 index 0000000..7482ca1 --- /dev/null +++ b/game/areas/area_base.tscn @@ -0,0 +1,77 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://areas/area_base.gd" type="Script" id=1] +[ext_resource path="res://areas/area_health_bar.tscn" type="PackedScene" id=2] + +[node name="area_base" type="Node2D" groups=[ +"areas", +]] + +script/script = ExtResource( 1 ) +max_health = 3 +health = 3 +activated = false +energy_cost = 0 +display_name = "" + +[node name="Sprite" type="Sprite" parent="."] + +[node name="area_health_bar" parent="." instance=ExtResource( 2 )] + +transform/pos = Vector2( -32.5694, -52.3751 ) + +[node name="Label" type="Label" parent="."] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -44.0 +margin/top = 49.0 +margin/right = 46.0 +margin/bottom = 63.0 +text = "Cost: 3 Energy" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="CheckButton" type="CheckButton" parent="."] + +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = -13.0 +margin/top = -64.0 +margin/right = 63.0 +margin/bottom = -42.0 +toggle_mode = true +enabled_focus_mode = 0 +shortcut = null +flat = false +align = 0 + +[node name="display_name" type="Label" parent="."] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -56.0 +margin/top = -85.0 +margin/right = 56.0 +margin/bottom = -71.0 +text = "Area Base" +align = 1 +valign = 1 +autowrap = true +uppercase = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[connection signal="game_area_health_changed" from="." to="area_health_bar" method="_on_area_base_game_area_health_changed"] + +[connection signal="toggled" from="CheckButton" to="." method="_on_CheckButton_toggled"] + + diff --git a/game/areas/area_health_bar.tscn b/game/areas/area_health_bar.tscn new file mode 100644 index 0000000..d763834 --- /dev/null +++ b/game/areas/area_health_bar.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://health_bar.gd" type="Script" id=1] +[ext_resource path="res://ui/wrench.tex" type="Texture" id=2] + +[node name="area_health_bar" type="Node2D"] + +script/script = ExtResource( 1 ) + +[node name="Sprite" type="Sprite" parent="."] + +transform/pos = Vector2( -11.8232, -2.31322 ) +texture = ExtResource( 2 ) + +[node name="Label" type="Label" parent="."] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = 1.0 +margin/top = -7.0 +margin/right = 41.0 +margin/bottom = 24.0 +text = "3 / 3" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/areas/canteen.tex b/game/areas/canteen.tex new file mode 100644 index 0000000..9ca7be2 Binary files /dev/null and b/game/areas/canteen.tex differ diff --git a/game/areas/canteen.tscn b/game/areas/canteen.tscn new file mode 100644 index 0000000..30b5a79 --- /dev/null +++ b/game/areas/canteen.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=4 format=1] + +[ext_resource path="res://areas/area_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://areas/canteen.tex" type="Texture" id=2] + +[sub_resource type="RectangleShape2D" id=1] + +custom_solver_bias = 0.0 +extents = Vector2( 43.8796, 47.0645 ) + +[node name="canteen" instance=ExtResource( 1 )] + +max_health = 2 +health = 0 +energy_cost = 2 +display_name = "Canteen" + +[node name="Sprite" parent="."] + +texture = ExtResource( 2 ) + +[node name="Area2D" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 1 ) +shapes/0/transform = Matrix32( 1, 0, 0, 1, 0, 0 ) +shapes/0/trigger = false +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +shape = SubResource( 1 ) +trigger = false +_update_shape_index = 0 + +[connection signal="input_event" from="Area2D" to="." method="_on_Area2D_input_event"] + + diff --git a/game/areas/command.tex b/game/areas/command.tex new file mode 100644 index 0000000..bdd9475 Binary files /dev/null and b/game/areas/command.tex differ diff --git a/game/areas/command.tscn b/game/areas/command.tscn new file mode 100644 index 0000000..3747fa8 --- /dev/null +++ b/game/areas/command.tscn @@ -0,0 +1,40 @@ +[gd_scene load_steps=4 format=1] + +[ext_resource path="res://areas/area_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://areas/command.tex" type="Texture" id=2] + +[sub_resource type="RectangleShape2D" id=1] + +custom_solver_bias = 0.0 +extents = Vector2( 46.2513, 47.0645 ) + +[node name="command" instance=ExtResource( 1 )] + +health = 1 +energy_cost = 4 +display_name = "Command" + +[node name="Sprite" parent="."] + +texture = ExtResource( 2 ) + +[node name="Area2D" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 1 ) +shapes/0/transform = Matrix32( 1, 0, 0, 1, 0, 0 ) +shapes/0/trigger = false +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +shape = SubResource( 1 ) +trigger = false +_update_shape_index = 0 + +[connection signal="input_event" from="Area2D" to="." method="_on_Area2D_input_event"] + + diff --git a/game/areas/engineering.gd b/game/areas/engineering.gd new file mode 100644 index 0000000..33cb9d1 --- /dev/null +++ b/game/areas/engineering.gd @@ -0,0 +1,10 @@ +extends "area_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass diff --git a/game/areas/engineering.tex b/game/areas/engineering.tex new file mode 100644 index 0000000..ed701f0 Binary files /dev/null and b/game/areas/engineering.tex differ diff --git a/game/areas/engineering.tscn b/game/areas/engineering.tscn new file mode 100644 index 0000000..26ea5cb --- /dev/null +++ b/game/areas/engineering.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=5 format=1] + +[ext_resource path="res://areas/area_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://areas/engineering.gd" type="Script" id=2] +[ext_resource path="res://areas/engineering.tex" type="Texture" id=3] + +[sub_resource type="RectangleShape2D" id=1] + +custom_solver_bias = 0.0 +extents = Vector2( 46.6591, 46.972 ) + +[node name="engineering" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +health = 1 +energy_cost = 5 +display_name = "Engineering" + +[node name="Sprite" parent="."] + +texture = ExtResource( 3 ) + +[node name="Area2D" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 1 ) +shapes/0/transform = Matrix32( 1, 0, 0, 1, 0, 0 ) +shapes/0/trigger = false +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +shape = SubResource( 1 ) +trigger = false +_update_shape_index = 0 + +[connection signal="input_event" from="Area2D" to="." method="_on_Area2D_input_event"] + + diff --git a/game/areas/reactor.gd b/game/areas/reactor.gd new file mode 100644 index 0000000..34feb1d --- /dev/null +++ b/game/areas/reactor.gd @@ -0,0 +1,11 @@ +extends "area_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here`1 + get_node('Label').hide() + get_node('CheckButton').hide() diff --git a/game/areas/reactor.tex b/game/areas/reactor.tex new file mode 100644 index 0000000..e784805 Binary files /dev/null and b/game/areas/reactor.tex differ diff --git a/game/areas/reactor.tscn b/game/areas/reactor.tscn new file mode 100644 index 0000000..a049934 --- /dev/null +++ b/game/areas/reactor.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=5 format=1] + +[ext_resource path="res://areas/area_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://areas/reactor.gd" type="Script" id=2] +[ext_resource path="res://areas/reactor.tex" type="Texture" id=3] + +[sub_resource type="RectangleShape2D" id=1] + +custom_solver_bias = 0.0 +extents = Vector2( 44.2412, 46.8488 ) + +[node name="reactor" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +max_health = 5 +health = 0 +display_name = "Reactor" + +[node name="Sprite" parent="."] + +texture = ExtResource( 3 ) + +[node name="Area2D" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 1 ) +shapes/0/transform = Matrix32( 1.0457, 0, 0, 1, -0.594147, 0 ) +shapes/0/trigger = false +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +transform/pos = Vector2( -0.594147, 0 ) +transform/scale = Vector2( 1.0457, 1 ) +shape = SubResource( 1 ) +trigger = false +_update_shape_index = 0 + +[connection signal="input_event" from="Area2D" to="." method="_on_Area2D_input_event"] + + diff --git a/game/areas/science.tex b/game/areas/science.tex new file mode 100644 index 0000000..33cfeef Binary files /dev/null and b/game/areas/science.tex differ diff --git a/game/areas/science.tscn b/game/areas/science.tscn new file mode 100644 index 0000000..61a9930 --- /dev/null +++ b/game/areas/science.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=4 format=1] + +[ext_resource path="res://areas/area_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://areas/science.tex" type="Texture" id=2] + +[sub_resource type="RectangleShape2D" id=1] + +custom_solver_bias = 0.0 +extents = Vector2( 46.2513, 47.0645 ) + +[node name="science" instance=ExtResource( 1 )] + +max_health = 2 +health = 0 +energy_cost = 5 +display_name = "Research Lab" + +[node name="Sprite" parent="."] + +texture = ExtResource( 2 ) + +[node name="Area2D" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 1 ) +shapes/0/transform = Matrix32( 1, 0, 0, 1, 0, 0 ) +shapes/0/trigger = false +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +shape = SubResource( 1 ) +trigger = false +_update_shape_index = 0 + +[connection signal="input_event" from="Area2D" to="." method="_on_Area2D_input_event"] + + diff --git a/game/areas/sixbay.tex b/game/areas/sixbay.tex new file mode 100644 index 0000000..c526065 Binary files /dev/null and b/game/areas/sixbay.tex differ diff --git a/game/areas/sixbay.tscn b/game/areas/sixbay.tscn new file mode 100644 index 0000000..45c38e9 --- /dev/null +++ b/game/areas/sixbay.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=4 format=1] + +[ext_resource path="res://areas/area_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://areas/sixbay.tex" type="Texture" id=2] + +[sub_resource type="RectangleShape2D" id=1] + +custom_solver_bias = 0.0 +extents = Vector2( 44.6702, 46.5375 ) + +[node name="sixbay" instance=ExtResource( 1 )] + +max_health = 2 +health = 0 +energy_cost = 3 +display_name = "Six Bay" + +[node name="Sprite" parent="."] + +texture = ExtResource( 2 ) + +[node name="Area2D" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 1 ) +shapes/0/transform = Matrix32( 1, 0, 0, 1, 0, 0 ) +shapes/0/trigger = false +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +shape = SubResource( 1 ) +trigger = false +_update_shape_index = 0 + +[connection signal="input_event" from="Area2D" to="." method="_on_Area2D_input_event"] + + diff --git a/game/cards/battery.gd b/game/cards/battery.gd new file mode 100644 index 0000000..e304a05 --- /dev/null +++ b/game/cards/battery.gd @@ -0,0 +1,15 @@ +extends "card_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" +export(int) var restore_strength + + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + +func _proc_effects(): + self.game.update_energy(self.restore_strength) \ No newline at end of file diff --git a/game/cards/battery_big.tscn b/game/cards/battery_big.tscn new file mode 100644 index 0000000..41ca86b --- /dev/null +++ b/game/cards/battery_big.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://cards/battery.gd" type="Script" id=2] + +[node name="card_base" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +display_name = "Big powerpack" +help = "Restores 6 energy" +restore_strength = 6 + +[node name="Label" type="Label" parent="CenterContainer"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -44.0 +margin/top = 9.0 +margin/right = 45.0 +margin/bottom = 60.0 +text = "A _big_ battery. ZZZZOT!" +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/cards/battery_small.tscn b/game/cards/battery_small.tscn new file mode 100644 index 0000000..2fb1588 --- /dev/null +++ b/game/cards/battery_small.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://cards/battery.gd" type="Script" id=2] + +[node name="card_base" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +display_name = "Small powerpack" +help = "Restores 3 energy" +restore_strength = 3 + +[node name="Label" type="Label" parent="CenterContainer"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -45.0 +margin/top = 8.0 +margin/right = 43.0 +margin/bottom = 61.0 +text = "A small battery pack. Bzzzzt." +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/cards/card_base.gd b/game/cards/card_base.gd index 820e350..526f372 100644 --- a/game/cards/card_base.gd +++ b/game/cards/card_base.gd @@ -4,47 +4,114 @@ extends Node2D # var a = 2 # var b = "textvar" export(bool) var confirm_state = 0 -var debug = true -var previous_location; +export(String) var display_name = '' +export(String) var help = '' +var debug = false +var previous_location var playing = 0 var play_timer = 0.0 var play_done_callback var game +var waiting_args = false +var arguments = [] +export(int) var args_required_to_play = 0 + +var click_target = null +var click_results = [] + func _ready(): # Called every time the node is added to the scene. # Initialization here set_process_input(true) set_process(true) + #set_fixed_process(true) if self.debug: get_node('debug').set_text('%s' % self) get_node('debug').show() - + +func _fixed_process(dt): + if self.click_target == null: + return + var results = get_world_2d().get_direct_space_state().intersect_point(self.click_target) + print(results) + self.click_results = click_results + self.click_target = null + func _process(dt): + if self.waiting_args == 1 && self.args_required_to_play <= 0: + self.end_card_play(true) if self.playing: self.play_timer -= dt - if self.play_timer <= 0: - self.play_timer = 0.0 - self.playing = 0 - if self.game: - if self.play_done_callback: - self.game.call(self.play_done_callback, self) - self.game = null + if self.play_timer <= 0 && self.playing: + self.end_card_play(true) + +func validate_args(): + return false + + +func on_waiting_args(): + if self.args_required_to_play <= 0: + return + self.set_scale(Vector2(1, 1)) + self.set_global_pos(Vector2(self.get_viewport().get_rect().size.x-50, 65)) + self.set_help(true) + +func set_help(enable): + if enable: + self.game.get_node('ui/help').set_text(self._card_help()) + else: + self.game.get_node('ui/help').set_text('') + +func _card_help(): + return "%d / %d targets required to play this card. Select then hit enter to confirm. Escape to cancel" % [self.arguments.size(), self.args_required_to_play] func _input(event): if not self.is_visible(): return - if event.type == InputEvent.KEY && event.scancode == KEY_ESCAPE && confirm_state == 1: - self.end_confirm_state(false) - if event.type == InputEvent.KEY && (event.scancode == KEY_RETURN || event.scancode == KEY_ENTER) && confirm_state == 1: - self.end_confirm_state(true) + if event.type == InputEvent.KEY && event.scancode == KEY_ESCAPE: + if self.confirm_state == 1: + self.end_confirm_state(false) + if self.waiting_args: + self.end_card_play(false) + if event.type == InputEvent.KEY && (event.scancode == KEY_RETURN || event.scancode == KEY_ENTER): + if self.confirm_state == 1: + self.end_confirm_state(true) + if self.waiting_args: + if self.validate_args(): + self.end_card_play(true) + +func _on_game_area_clicked(area): + if not self.waiting_args: + return + self.add_card_arg(area) + +func add_card_arg(node): + if not self.validate_argument(node): + return + var i = self.arguments.find(node) + if i != -1: + # Already in arguments. De-select instead + self.arguments[i].set_hilight(false) + self.arguments.remove(i) + self.set_help(true) + return + if self.arguments.size() >= self.args_required_to_play: + var a = self.arguments[0] + a.set_hilight(false) + self.arguments.pop_front() + self.arguments.append(node) + node.set_hilight(true) + self.set_help(true) + +func validate_argument(node): + pass func enter_confirm_state(): if confirm_state == 1: return - var game = get_node('/root/game') - if game: - var hand = game.get('hand') - game.get_node('ui/help').set_text('Press "Enter" to play the card; Press "Escape" to cancel') + if self.game: + var hand = self.game.get('hand') + self.game.get_node('ui/help').set_text('Press "Enter" to play the card; Press "Escape" to cancel') for i in hand: if i.confirm_state == 1: i.end_confirm_state(false); @@ -63,29 +130,77 @@ func end_confirm_state(play_card): return confirm_state = 0 self.set_scale(Vector2(1, 1)) - print(self.previous_location) self.set_global_pos(self.previous_location) self.set_z(self.get_z()-1) get_node('Controls').hide() - var game = get_node('/root/game') - if game: - game.get_node('ui/help').set_text('') + if self.game: + self.game.get_node('ui/help').set_text('') if play_card: - game.play_card(self) + self.game.play_card(self) func _on_click_base_input_event( viewport, event, shape_idx ): if not self.is_visible(): return if event.type == InputEvent.MOUSE_BUTTON && event.button_index == BUTTON_LEFT && event.pressed: - if confirm_state != 1: - self.enter_confirm_state() - return self - else: - pass + pass + else: + return + # Possibly being chosen by another card + if self.game.game_state == 1: + var c + var card + var cards = self.game.get_tree().get_nodes_in_group('cards') + for c in cards: + if c == self: + continue + if ! c.is_visible(): + continue + if c.waiting_args == 1: + card = c + if card: + card.add_card_arg(self) + if self.game.game_state != 0: + return + if confirm_state != 1: + self.enter_confirm_state() + return self -func proc_effects(game, callback = null): +func start_card_play(callback = null): + print("Starting play of %s" % self.display_name) if callback: self.play_done_callback = callback - self.game = game - self.playing = 1 - print('Playing card %s' % self) \ No newline at end of file + self.playing = 0 + self.waiting_args = 1 + self.on_waiting_args() + +func end_card_play(play = false): + print("Ending play of %s (%s)" % [ self.display_name, play]) + if play: + self._proc_effects() + self.set_global_pos(self.previous_location) + self.playing = 0 + self.play_timer = 0.0 + self.waiting_args = 0 + for a in arguments: + a.set_hilight(false) + self.arguments = [] + if self.game && self.play_done_callback: + self.game.call(self.play_done_callback, self, play) + if self.game: + self.game.get_node('ui/help').set_text('') + +func set_game(game): + self.game = game + # @TODO maybe a signal from the game when areas are added/removed + var areas = self.game.get_tree().get_nodes_in_group('areas') + for area in areas: + area.connect('game_area_clicked', self, '_on_game_area_clicked') + +func _proc_effects(): + pass + +func set_hilight(enable): + if enable: + get_node('Sprite').set_modulate(Color(0, 1, 0, 1)) + else: + get_node('Sprite').set_modulate(Color(1, 1, 1, 1)) \ No newline at end of file diff --git a/game/cards/card_base.tscn b/game/cards/card_base.tscn index 608f609..fc247cc 100644 --- a/game/cards/card_base.tscn +++ b/game/cards/card_base.tscn @@ -11,10 +11,15 @@ custom_solver_bias = 0.0 extents = Vector2( 50, 75 ) -[node name="card_base" type="Node2D"] +[node name="card_base" type="Node2D" groups=[ +"cards", +]] script/script = ExtResource( 1 ) confirm_state = 0 +display_name = "" +help = "" +args_required_to_play = 0 [node name="Sprite" type="Sprite" parent="."] @@ -26,7 +31,7 @@ texture = ExtResource( 2 ) input/pickable = true shapes/0/shape = SubResource( 1 ) -shapes/0/transform = Matrix32( 1, 0, 0, 1, -0.583984, 8.46769 ) +shapes/0/transform = Matrix32( 1, 0, 0, 0.878521, -0.583984, -1.0077 ) shapes/0/trigger = false gravity_vec = Vector2( 0, 1 ) gravity = 98.0 @@ -36,7 +41,8 @@ script/script = ExtResource( 3 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="click_base"] -transform/pos = Vector2( -0.583984, 8.46769 ) +transform/pos = Vector2( -0.583984, -1.0077 ) +transform/scale = Vector2( 1, 0.878521 ) z/z = 1 shape = SubResource( 1 ) trigger = false diff --git a/game/cards/card_repair.gd b/game/cards/card_repair.gd new file mode 100644 index 0000000..742d3dd --- /dev/null +++ b/game/cards/card_repair.gd @@ -0,0 +1,26 @@ +extends "card_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + +func validate_args(): + if self.arguments.size() == 1: + var n = self.arguments[0] + if n.health < n.max_health: + return true + return false + +func validate_argument(node): + if node.is_in_group('areas'): + return true + return false + +func _proc_effects(): + var n = self.arguments[0] + n.set_health(n.health + 1) \ No newline at end of file diff --git a/game/cards/card_repair.tscn b/game/cards/card_repair.tscn index c0c41e0..956f876 100644 --- a/game/cards/card_repair.tscn +++ b/game/cards/card_repair.tscn @@ -1,7 +1,37 @@ -[gd_scene load_steps=2 format=1] +[gd_scene load_steps=4 format=1] [ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://cards/card_repair.gd" type="Script" id=2] +[ext_resource path="res://ui/wrench.tex" type="Texture" id=3] [node name="card_repair" instance=ExtResource( 1 )] +script/script = ExtResource( 2 ) +display_name = "Repair" +help = "Fix one damange from a ship area" +args_required_to_play = 1 + +[node name="Sprite 2" type="Sprite" parent="."] + +transform/pos = Vector2( 2.7805, -32.9688 ) +transform/scale = Vector2( 2, 2 ) +texture = ExtResource( 3 ) + +[node name="Label" type="Label" parent="."] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -46.0 +margin/top = -5.0 +margin/right = 44.0 +margin/bottom = 80.0 +text = "Repairs 1 (one) damage for a selected area." +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + diff --git a/game/cards/injured.gd b/game/cards/injured.gd new file mode 100644 index 0000000..3479ea0 --- /dev/null +++ b/game/cards/injured.gd @@ -0,0 +1,30 @@ +extends "card_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + +func validate_args(): + if self.arguments.size() == 1: + var a = self.arguments[0] + if a == self.game.get_node('areas/sixbay'): + if a.activated: + return true + return false + +func validate_argument(node): + if node.is_in_group('areas'): + return true + return false + +func _proc_effects(): + self.game.add_card_to_deck() + self.game.destroy_card(self) + +func _card_help(): + return 'Use on activated six bay to remove this card and get a new card put in your deck. Arguments %d / %d' %[self.arguments.size(), self.args_required_to_play] \ No newline at end of file diff --git a/game/cards/injured.tscn b/game/cards/injured.tscn new file mode 100644 index 0000000..e43e71f --- /dev/null +++ b/game/cards/injured.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://cards/injured.gd" type="Script" id=2] + +[node name="injured" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +display_name = "Injured Crewmember" +help = "Play on actiavted medbay to turn into another card" +args_required_to_play = 1 + +[node name="Label" type="Label" parent="CenterContainer"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -44.0 +margin/top = 9.0 +margin/right = 47.0 +margin/bottom = 61.0 +text = "You gotta help me - I'm injured!" +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/cards/medkit.gd b/game/cards/medkit.gd new file mode 100644 index 0000000..ed3b7ea --- /dev/null +++ b/game/cards/medkit.gd @@ -0,0 +1,29 @@ +extends "card_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + +func validate_args(): + if self.arguments.size() == 1: + var a = self.arguments[0] + # @Bug Shady shit which will break + if a.is_in_group('cards') && a.display_name == 'Injured Crewmember': + return true + return false + +func validate_argument(node): + if node.is_in_group('cards'): + return true + return false + +func _proc_effects(): + self.game.destroy_card(self.arguments[0]) + +func _card_help(): + return 'Use on an injured crewmember in your hand to heal them and remove the card from the game. Arguments %d / %d' %[self.arguments.size(), self.args_required_to_play] \ No newline at end of file diff --git a/game/cards/medkit.tscn b/game/cards/medkit.tscn new file mode 100644 index 0000000..cd897a4 --- /dev/null +++ b/game/cards/medkit.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://cards/medkit.gd" type="Script" id=2] + +[node name="card_base" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +display_name = "Medkit" +help = "Play on an injured crewmember in your hand to heal them" +args_required_to_play = 1 + +[node name="Label" type="Label" parent="CenterContainer"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -39.0 +margin/top = -51.0 +margin/right = 51.0 +margin/bottom = 49.0 +text = "A bag of syringes and bandages. Maybe someone needs help?" +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/cards/repurpose.gd b/game/cards/repurpose.gd new file mode 100644 index 0000000..40a950f --- /dev/null +++ b/game/cards/repurpose.gd @@ -0,0 +1,36 @@ +extends "card_base.gd" + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + +func _card_help(): + return "Select one area and one card. The card will be destroyed, and the area will be repaired by 1. Arguments: %d / %d. Press enter to confirm, escape to cancel" % [self.arguments.size(), self.args_required_to_play] + +func validate_args(): + if self.arguments.size() == 2: + var a = self.arguments[0] + var b = self.arguments[1] + if (a.is_in_group('areas') && b.is_in_group('cards')): + return true + if (a.is_in_group('cards') && b.is_in_group('areas')): + return true + return false + return false + +func validate_argument(node): + if node.is_in_group('areas') || node.is_in_group('cards'): + return true + return false + +func _proc_effects(): + for a in self.arguments: + if a.is_in_group('cards'): + self.game.destroy_card(a) + if a.is_in_group('areas'): + a.set_health(a.health + 1) \ No newline at end of file diff --git a/game/cards/repurpose.tscn b/game/cards/repurpose.tscn new file mode 100644 index 0000000..6ed50c5 --- /dev/null +++ b/game/cards/repurpose.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] +[ext_resource path="res://cards/repurpose.gd" type="Script" id=2] + +[node name="card_base" instance=ExtResource( 1 )] + +script/script = ExtResource( 2 ) +display_name = "Repurpose" +help = "Destroy a card in your hand to repair a ship area by 1" +args_required_to_play = 2 + +[node name="Label" type="Label" parent="CenterContainer"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -44.0 +margin/top = -7.0 +margin/right = 46.0 +margin/bottom = 60.0 +text = "Gotta break something to make something." +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/cards/spare_parts.tscn b/game/cards/spare_parts.tscn new file mode 100644 index 0000000..9d2d217 --- /dev/null +++ b/game/cards/spare_parts.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=2 format=1] + +[ext_resource path="res://cards/card_base.tscn" type="PackedScene" id=1] + +[node name="spare parts" instance=ExtResource( 1 )] + +display_name = "Spare Parts" +help = "This card does nothing" + +[node name="Label" type="Label" parent="CenterContainer"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = -46.0 +margin/top = -60.0 +margin/right = 52.0 +margin/bottom = 62.0 +text = "A handful of bolts and widgets. Useful somewhere, but not here and not now." +autowrap = true +clip_text = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/game/engine.cfg b/game/engine.cfg index 5f46ff9..6c50a23 100644 --- a/game/engine.cfg +++ b/game/engine.cfg @@ -1,6 +1,6 @@ [application] -name="ld39" +name="Dead in the Water" main_scene="res://game.tscn" icon="res://icon.png" diff --git a/game/game.gd b/game/game.gd index e243cad..f5faeb3 100644 --- a/game/game.gd +++ b/game/game.gd @@ -6,12 +6,14 @@ signal game_deck_changed signal game_discard_changed signal game_hand_changed signal game_state_changed +signal game_round_start -var DEBUG = true +var DEBUG = false # class member variables go here, for example: # var a = 2 # var b = "textvar" -var energy = 100 +export(int) var energy = 100 +export(int) var base_energy_per_round = 10 const ENERGY_MAX = 100 const ENERGY_MIN = 0 const SHUFFLE_REPEATS = 3 @@ -45,6 +47,12 @@ var game_states = { # Cards var cards = { "card_repair": preload("res://cards/card_repair.tscn"), + "card_repurpose": preload("res://cards/repurpose.tscn"), + "card_battery_small": preload("res://cards/battery_small.tscn"), + "card_battery_big": preload("res://cards/battery_big.tscn"), + "card_spare_parts": preload("res://cards/spare_parts.tscn"), + "card_injured": preload('res://cards/injured.tscn'), + "card_medkit": preload('res://cards/medkit.tscn'), } func _ready(): @@ -55,24 +63,67 @@ func _ready(): bar.set_min(ENERGY_MIN) bar.set_max(ENERGY_MAX) set_process(true) + get_node('ui/end_message/buttons/Replay').connect('pressed', self, 'on_game_replay') + get_node('ui/end_message/buttons/Quit').connect('pressed', self, 'on_game_quit') if self.DEBUG: get_node('ui/debug').show() + var areas = self.get_tree().get_nodes_in_group('areas') + for a in areas: + a.connect('game_area_activation_changed', self, 'on_area_activation_changed') + self.on_area_activation_changed(null, null) init_game() func init_game(): # Popuplate deck - var card_keys = self.cards.keys() + self.energy = ENERGY_MAX + get_node('ui/EnergyHolder/ProgressBar').set_value(self.energy) + self.deck = [] + # Choose starting deck: + self.add_card_to_deck('card_medkit') + self.add_card_to_deck('card_repurpose') + self.add_card_to_deck('card_spare_parts') + self.add_card_to_deck('card_spare_parts') + self.add_card_to_deck('card_spare_parts') + self.add_card_to_deck('card_injured') + self.add_card_to_deck('card_injured') + self.add_card_to_deck('card_injured') + self.add_card_to_deck('card_battery_small') + self.add_card_to_deck('card_battery_small') + self.discard = [] + self.hand = [] while self.deck.size() < STARTING_DECK_SIZE: - var node = self.cards[card_keys[rand_range(0, card_keys.size() - 1)]].instance() - node.add_to_group('cards') - get_node('cards').add_child(node) - node.hide() - self.deck.append(node) + self.add_card_to_deck(null) self.shuffle() emit_signal('game_deck_changed', self.deck.size()) + emit_signal('game_hand_changed', self.hand.size()) + emit_signal('game_discard_changed', self.discard.size()) + get_node('areas/reactor').set_health(0) self.update_game_state(-1) +func add_card_to_deck(key = null): + """ + If key is null, a card is randomly added + @returns bool + true is a card was added, false otherwise + """ + var node + if not key: + var card_keys = self.cards.keys() + node = self.cards[card_keys[rand_range(0, card_keys.size() - 1)]].instance() + elif self.cards.has(key): + node = self.cards[key].instance() + else: + return false + node.add_to_group('cards') + node.set_game(self) + get_node('cards').add_child(node) + node.hide() + self.deck.append(node) + return true + func update_game_state(new_state_idx): + if self.game_state == new_state_idx: + return if ! self.game_states.has(new_state_idx): print("Error: trying to change game_state to unknown index: %d" % new_state_idx) return @@ -85,6 +136,9 @@ func _process(): pass func update_energy(diff = 0): + if self.energy + diff > self.ENERGY_MAX: + diff = self.ENERGY_MAX - self.energy + print('Updating energy from %d by %d to %d' % [self.energy, diff, self.energy + diff]) self.energy += diff emit_signal("game_energy_changed", self.energy) if self.energy <= 0: @@ -109,7 +163,6 @@ func draw_card(): """ if self.hand.size() >= self.max_hand_size: return false # Can't exceed max hand size - print(self.deck.size()) if self.deck.size() == 0: self.shuffle_in_discard() if self.deck.empty(): @@ -117,6 +170,7 @@ func draw_card(): var c = self.deck[-1] self.deck.pop_back() self.hand.push_back(c) + c.previous_location = Vector2(-200, -200) emit_signal("game_deck_changed", self.deck.size()) emit_signal("game_hand_changed", self.hand.size()) return true @@ -150,18 +204,35 @@ func _on_game_game_state_changed(old_state, new_state): self.round_counter += 1 self.actions_remaining = self.actions_per_round self.draw_hand() + print("New round: %d" %self.round_counter) emit_signal("game_round_start", self.round_counter) self.update_game_state(0) # Waiting for player action - if new_state == 3: # Round done + if new_state == 2: # Round done var state_changed = self.update_energy(-get_round_energy_cost()) + state_changed = state_changed || self.check_reactor_fixed() if not state_changed: self.update_game_state(-1) if new_state == 5: # Game finish - get_node('ui/help').set_text(self.game_over_message) + var n = get_node('ui/end_message') + n.set_message(self.game_over_message) + n.show() func play_card(card): if self.game_state != 0: return + card.start_card_play('on_card_play_done') + self.update_game_state(1) # playing action + +func on_card_play_done(card, played): + if not played: + self.update_game_state(0) # Waiting for player input + return + self.discard_card(card) + self.actions_remaining -= 1 + if self.actions_remaining <= 0: + self.update_game_state(2) # Round done + +func discard_card(card): card.hide() card.set_global_pos(Vector2(-200,-200)) var p = self.hand.find(card) @@ -173,14 +244,44 @@ func play_card(card): print(self.discard) emit_signal('game_hand_changed', self.hand.size()) emit_signal('game_discard_changed', self.discard.size()) - card.proc_effects(self, 'on_card_play_done') - self.update_game_state(1) # playing action - -func on_card_play_done(card): - self.actions_remaining -= 1 - if self.actions_remaining <= 0: - self.update_game_state(3) - + func get_round_energy_cost(): # @TODO base on enabled areas - return 10 \ No newline at end of file + var areas = get_tree().get_nodes_in_group('areas') + var cost = self.base_energy_per_round + for a in areas: + if a.activated: + cost += a.energy_cost + return cost + +func check_reactor_fixed(): + var n = get_node('areas/reactor') + if n.health == n.max_health: + self.game_win = true + self.game_over_message = 'Fixed the reactor - back on track and in it to win it :)' + self.update_game_state(5) + return true + return false + +func on_game_quit(): + get_tree().quit() + +func on_game_replay(): + get_tree().change_scene('res://game.tscn') + #get_node('ui/end_message').hide() + #self.init_game() + +func on_area_activation_changed(area, activated): + var c = get_round_energy_cost() + get_node('ui/round_energy_label').set_text('Energy Consumption: %d' % c) + +func destroy_card(card): + # Remove a card from the game + for ar in [self.hand, self.deck, self.discard]: + var i = ar.find(card) + if i != -1: + ar.remove(i) + self.remove_child(card) + emit_signal('game_hand_changed', self.hand.size()) + emit_signal('game_discard_changed', self.discard.size()) + emit_signal('game_deck_changed', self.deck.size()) \ No newline at end of file diff --git a/game/game.tscn b/game/game.tscn index d2a0dc7..c57f1d7 100644 --- a/game/game.tscn +++ b/game/game.tscn @@ -1,18 +1,27 @@ -[gd_scene load_steps=14 format=1] +[gd_scene load_steps=23 format=1] [ext_resource path="res://game.gd" type="Script" id=1] -[ext_resource path="res://ui_hand.gd" type="Script" id=2] -[ext_resource path="res://ui/hand_border.tex" type="Texture" id=3] -[ext_resource path="res://ui/energy_bar.gd" type="Script" id=4] -[ext_resource path="res://ui/empty-bar.tex" type="Texture" id=5] -[ext_resource path="res://ui/full-bar.tex" type="Texture" id=6] -[ext_resource path="res://ui/energy.tex" type="Texture" id=7] -[ext_resource path="res://ui/black.tex" type="Texture" id=8] -[ext_resource path="res://ui/discard_deck.tscn" type="PackedScene" id=9] -[ext_resource path="res://ui/deck.tscn" type="PackedScene" id=10] -[ext_resource path="res://ui/starfield.tscn" type="PackedScene" id=11] -[ext_resource path="res://debug.gd" type="Script" id=12] -[ext_resource path="res://help.gd" type="Script" id=13] +[ext_resource path="res://areas/reactor.tscn" type="PackedScene" id=2] +[ext_resource path="res://areas/engineering.tscn" type="PackedScene" id=3] +[ext_resource path="res://areas/command.tscn" type="PackedScene" id=4] +[ext_resource path="res://areas/canteen.tscn" type="PackedScene" id=5] +[ext_resource path="res://areas/science.tscn" type="PackedScene" id=6] +[ext_resource path="res://areas/sixbay.tscn" type="PackedScene" id=7] +[ext_resource path="res://ui/ship.tex" type="Texture" id=8] +[ext_resource path="res://ui_hand.gd" type="Script" id=9] +[ext_resource path="res://ui/hand_border.tex" type="Texture" id=10] +[ext_resource path="res://ui/energy_bar.gd" type="Script" id=11] +[ext_resource path="res://ui/empty-bar.tex" type="Texture" id=12] +[ext_resource path="res://ui/full-bar.tex" type="Texture" id=13] +[ext_resource path="res://ui/energy.tex" type="Texture" id=14] +[ext_resource path="res://ui/black.tex" type="Texture" id=15] +[ext_resource path="res://ui/discard_deck.tscn" type="PackedScene" id=16] +[ext_resource path="res://ui/deck.tscn" type="PackedScene" id=17] +[ext_resource path="res://ui/starfield.tscn" type="PackedScene" id=18] +[ext_resource path="res://debug.gd" type="Script" id=19] +[ext_resource path="res://help.gd" type="Script" id=20] +[ext_resource path="res://ui/end_message.tscn" type="PackedScene" id=21] +[ext_resource path="res://ui/help_widget.tscn" type="PackedScene" id=22] [node name="game" type="Node2D"] @@ -21,28 +30,64 @@ script/script = ExtResource( 1 ) __meta__ = { "_edit_lock_": true } +energy = 100 +base_energy_per_round = 8 [node name="cards" type="Node2D" parent="."] +[node name="areas" type="Node2D" parent="."] + +editor/display_folded = true + +[node name="reactor" parent="areas" instance=ExtResource( 2 )] + +transform/pos = Vector2( 150, 250 ) + +[node name="engineering" parent="areas" instance=ExtResource( 3 )] + +transform/pos = Vector2( 275, 250 ) + +[node name="command" parent="areas" instance=ExtResource( 4 )] + +transform/pos = Vector2( 775, 250 ) + +[node name="canteen" parent="areas" instance=ExtResource( 5 )] + +transform/pos = Vector2( 650, 250 ) + +[node name="science" parent="areas" instance=ExtResource( 6 )] + +transform/pos = Vector2( 525, 250 ) + +[node name="sixbay" parent="areas" instance=ExtResource( 7 )] + +transform/pos = Vector2( 400, 250 ) + +[node name="Sprite" type="Sprite" parent="areas"] + +transform/pos = Vector2( 495.695, 236.953 ) +z/z = -1 +texture = ExtResource( 8 ) + [node name="ui" type="Node2D" parent="."] [node name="HandHolder" type="Node2D" parent="ui"] transform/pos = Vector2( 142.702, 494.652 ) -script/script = ExtResource( 2 ) +script/script = ExtResource( 9 ) [node name="Background" type="Sprite" parent="ui/HandHolder"] visibility/behind_parent = true transform/pos = Vector2( 373.51, 38.9889 ) z/z = -1 -texture = ExtResource( 3 ) +texture = ExtResource( 10 ) [node name="EnergyHolder" type="Node2D" parent="ui"] transform/pos = Vector2( -0.527039, -7.28315 ) transform/scale = Vector2( 0.95, 0.95 ) -script/script = ExtResource( 4 ) +script/script = ExtResource( 11 ) __meta__ = { "_edit_lock_": true } @@ -60,14 +105,14 @@ margin/right = 54.0 margin/bottom = 481.0 range/min = 0.0 range/max = 100.0 -range/step = 1.0 +range/step = 0.5 range/page = 0.0 range/value = 100.0 range/exp_edit = false range/rounded = false -texture/under = ExtResource( 5 ) +texture/under = ExtResource( 12 ) texture/over = null -texture/progress = ExtResource( 6 ) +texture/progress = ExtResource( 13 ) mode = 3 radial_fill/fill_degrees = 360.0 radial_fill/center_offset = Vector2( 0, 0 ) @@ -75,13 +120,13 @@ radial_fill/center_offset = Vector2( 0, 0 ) [node name="icon" type="Sprite" parent="ui/EnergyHolder"] transform/pos = Vector2( 28, 35 ) -texture = ExtResource( 7 ) +texture = ExtResource( 14 ) [node name="icon-bg" type="Sprite" parent="ui/EnergyHolder/icon"] transform/scale = Vector2( 0.8125, 0.8125 ) z/z = -1 -texture = ExtResource( 8 ) +texture = ExtResource( 15 ) [node name="Label" type="Label" parent="ui/EnergyHolder"] @@ -105,25 +150,26 @@ max_lines_visible = -1 transform/scale = Vector2( 1.625, 0.625 ) z/z = -1 -texture = ExtResource( 8 ) +texture = ExtResource( 15 ) centered = false -[node name="discard" parent="ui" instance=ExtResource( 9 )] +[node name="discard" parent="ui" instance=ExtResource( 16 )] transform/pos = Vector2( 973.566, 533.945 ) -[node name="deck" parent="ui" instance=ExtResource( 10 )] +[node name="deck" parent="ui" instance=ExtResource( 17 )] transform/pos = Vector2( 59.459, 532.687 ) -[node name="starfield" parent="ui" instance=ExtResource( 11 )] +[node name="starfield" parent="ui" instance=ExtResource( 18 )] z/z = -2 [node name="debug" type="Node2D" parent="ui"] +visibility/visible = false transform/pos = Vector2( 469.232, 34.61 ) -script/script = ExtResource( 12 ) +script/script = ExtResource( 19 ) [node name="deckCount" type="Label" parent="ui/debug"] @@ -178,10 +224,44 @@ margin/top = 10.0 margin/right = 750.0 margin/bottom = 110.0 align = 1 +autowrap = true +clip_text = true +uppercase = true percent_visible = 1.0 lines_skipped = 0 max_lines_visible = -1 -script/script = ExtResource( 13 ) +script/script = ExtResource( 20 ) + +[node name="end_message" parent="ui" instance=ExtResource( 21 )] + +visibility/visible = false +transform/pos = Vector2( 266.419, 92.0803 ) +z/z = 1 + +[node name="round_energy_label" type="Label" parent="ui"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = 31.0 +margin/top = 3.0 +margin/right = 181.0 +margin/bottom = 53.0 +text = "Energy Consumption: 2" +align = 1 +valign = 1 +autowrap = true +uppercase = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="help_widget" parent="ui" instance=ExtResource( 22 )] + +margin/left = 176.0 +margin/right = 228.0 +margin/bottom = 52.0 [connection signal="game_deck_changed" from="." to="ui/debug" method="_on_game_game_deck_changed"] diff --git a/game/health_bar.gd b/game/health_bar.gd new file mode 100644 index 0000000..1a835c3 --- /dev/null +++ b/game/health_bar.gd @@ -0,0 +1,19 @@ +extends Node2D + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + + + +func _on_area_base_game_area_health_changed(old, new, max_health): + get_node('Label').set_text('%d / %d' %[new, max_health]) + + +func _on_reactor_game_area_health_changed(old, new, max_health): + self._on_area_base_game_area_health_changed(old, new, max_health) diff --git a/game/help_widget.gd b/game/help_widget.gd new file mode 100644 index 0000000..ed01a2f --- /dev/null +++ b/game/help_widget.gd @@ -0,0 +1,60 @@ +extends TextureButton + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" +var widget_shown = false +var current_texture_idx = 0 +var textures = [ + load('res://ui/help/help_1.tex'), + load('res://ui/help/help_2.tex'), + load('res://ui/help/help_3.tex'), + load('res://ui/help/help_4.tex'), +] + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + set_process_unhandled_key_input(true) + +func _unhandled_key_input(event): + if not self.widget_shown: + return + if event.type == InputEvent.KEY && event.scancode == KEY_ESCAPE: + self.show_widget(false) + get_tree().set_input_as_handled() + +func show_widget(enable): + self.widget_shown = enable + if enable: + self.set_widget_page(self.current_texture_idx) + get_node('Container').show() + else: + get_node('Container').hide() + self.set_widget_page(0) + +func _on_icon_pressed(): + self.show_widget(!self.widget_shown) + +func set_widget_page(idx): + if idx < 0: + return + if idx >= self.textures.size(): + return + get_node('Container/TextureFrame').set_texture(self.textures[idx]) + get_node('Container/Label').set_text("Page %d / %d" % [idx + 1, self.textures.size() ]) + if idx == 0: + get_node('Container/Previous').set_disabled(true) + else: + get_node('Container/Previous').set_disabled(false) + if idx == self.textures.size() - 1: + get_node('Container/Next').set_disabled(true) + else: + get_node('Container/Next').set_disabled(false) + self.current_texture_idx = idx + +func _on_Next_pressed(): + self.set_widget_page(self.current_texture_idx + 1) + +func _on_Previous_pressed(): + self.set_widget_page(self.current_texture_idx - 1) diff --git a/game/ui/end_message.gd b/game/ui/end_message.gd new file mode 100644 index 0000000..46aedeb --- /dev/null +++ b/game/ui/end_message.gd @@ -0,0 +1,13 @@ +extends Node2D + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called every time the node is added to the scene. + # Initialization here + pass + +func set_message(text): + get_node('buttons/Label').set_text(text) \ No newline at end of file diff --git a/game/ui/end_message.tscn b/game/ui/end_message.tscn new file mode 100644 index 0000000..2256d34 --- /dev/null +++ b/game/ui/end_message.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=3 format=1] + +[ext_resource path="res://ui/end_message.gd" type="Script" id=1] +[ext_resource path="res://ui/end_text_bg.tex" type="Texture" id=2] + +[node name="Node2D" type="Node2D"] + +script/script = ExtResource( 1 ) + +[node name="Node2D" type="Node2D" parent="."] + +z/z = -1 + +[node name="Sprite3D" type="Sprite" parent="Node2D"] + +transform/pos = Vector2( -5.30737, -3.98053 ) +z/z = 1 +texture = ExtResource( 2 ) +centered = false + +[node name="buttons" type="Node2D" parent="."] + +[node name="Label" type="Label" parent="buttons"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = 5.0 +margin/top = 5.0 +margin/right = 505.0 +margin/bottom = 305.0 +align = 1 +valign = 1 +autowrap = true +clip_text = true +uppercase = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="Replay" type="Button" parent="buttons"] + +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = 165.0 +margin/top = 282.0 +margin/right = 240.0 +margin/bottom = 304.0 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +text = "Replay" +flat = false + +[node name="Quit" type="Button" parent="buttons"] + +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = 253.0 +margin/top = 282.0 +margin/right = 328.0 +margin/bottom = 304.0 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +text = "Quit" +flat = false + + diff --git a/game/ui/end_text_bg.tex b/game/ui/end_text_bg.tex new file mode 100644 index 0000000..cffe145 Binary files /dev/null and b/game/ui/end_text_bg.tex differ diff --git a/game/ui/help.tex b/game/ui/help.tex new file mode 100644 index 0000000..74de2d8 Binary files /dev/null and b/game/ui/help.tex differ diff --git a/game/ui/help/help_1.tex b/game/ui/help/help_1.tex new file mode 100644 index 0000000..f745640 Binary files /dev/null and b/game/ui/help/help_1.tex differ diff --git a/game/ui/help/help_2.tex b/game/ui/help/help_2.tex new file mode 100644 index 0000000..6771657 Binary files /dev/null and b/game/ui/help/help_2.tex differ diff --git a/game/ui/help/help_3.tex b/game/ui/help/help_3.tex new file mode 100644 index 0000000..6da280c Binary files /dev/null and b/game/ui/help/help_3.tex differ diff --git a/game/ui/help/help_4.tex b/game/ui/help/help_4.tex new file mode 100644 index 0000000..c72f9d9 Binary files /dev/null and b/game/ui/help/help_4.tex differ diff --git a/game/ui/help_widget.tscn b/game/ui/help_widget.tscn new file mode 100644 index 0000000..3f02514 --- /dev/null +++ b/game/ui/help_widget.tscn @@ -0,0 +1,106 @@ +[gd_scene load_steps=4 format=1] + +[ext_resource path="res://ui/help.tex" type="Texture" id=1] +[ext_resource path="res://help_widget.gd" type="Script" id=2] +[ext_resource path="res://ui/help/help_1.tex" type="Texture" id=3] + +[node name="icon" type="TextureButton"] + +hint/tooltip = "Learn how to play the game" +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = 0.0 +margin/top = 0.0 +margin/right = 0.0 +margin/bottom = 0.0 +toggle_mode = false +enabled_focus_mode = 0 +shortcut = null +textures/normal = ExtResource( 1 ) +params/resize_mode = 0 +params/stretch_mode = 0 +script/script = ExtResource( 2 ) + +[node name="Container" type="Container" parent="."] + +visibility/visible = false +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = -173.0 +margin/top = 13.0 +margin/right = -133.0 +margin/bottom = 53.0 + +[node name="TextureFrame" type="TextureFrame" parent="Container"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = 94.0 +margin/top = 25.0 +margin/right = 944.0 +margin/bottom = 525.0 +texture = ExtResource( 3 ) +stretch_mode = 0 + +[node name="Previous" type="Button" parent="Container"] + +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = 95.0 +margin/top = 533.0 +margin/right = 264.0 +margin/bottom = 587.0 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +text = "Previous Page" +flat = false + +[node name="Next" type="Button" parent="Container"] + +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +margin/left = 788.0 +margin/top = 532.0 +margin/right = 947.0 +margin/bottom = 587.0 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +text = "Next Page" +flat = false + +[node name="Label" type="Label" parent="Container"] + +focus/ignore_mouse = true +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 0 +margin/left = 387.0 +margin/top = 541.0 +margin/right = 628.0 +margin/bottom = 575.0 +text = "Page 1 / 1" +align = 1 +valign = 1 +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[connection signal="pressed" from="." to="." method="_on_icon_pressed"] + +[connection signal="pressed" from="Container/Previous" to="." method="_on_Previous_pressed"] + +[connection signal="pressed" from="Container/Next" to="." method="_on_Next_pressed"] + + diff --git a/game/ui/ship.tex b/game/ui/ship.tex new file mode 100644 index 0000000..a7a71fa Binary files /dev/null and b/game/ui/ship.tex differ diff --git a/game/ui/wrench.tex b/game/ui/wrench.tex new file mode 100644 index 0000000..281b07c Binary files /dev/null and b/game/ui/wrench.tex differ diff --git a/game/ui_hand.gd b/game/ui_hand.gd index 3a74431..6fb8976 100644 --- a/game/ui_hand.gd +++ b/game/ui_hand.gd @@ -17,9 +17,16 @@ func _on_game_game_hand_changed(count): var origin = self.get_global_pos() var offset = Vector2(25, 39) var hand = game.get('hand') + print(hand.size()) for i in range(0, hand.size()): var card = hand[i] if not card: continue card.set_global_pos(origin + offset + Vector2(i*100, 0)) card.show() + var cards = game.get_tree().get_nodes_in_group('cards') + for c in cards: + var i = hand.find(c) + if i == -1: + c.previous_location = Vector2(-200, -200) + c.hide() \ No newline at end of file diff --git a/source_assets/icons/help.png b/source_assets/icons/help.png new file mode 100644 index 0000000..ad27241 Binary files /dev/null and b/source_assets/icons/help.png differ diff --git a/source_assets/icons/help.xcf b/source_assets/icons/help.xcf new file mode 100644 index 0000000..d34af3f Binary files /dev/null and b/source_assets/icons/help.xcf differ diff --git a/source_assets/icons/wrench.png b/source_assets/icons/wrench.png new file mode 100644 index 0000000..63599f0 Binary files /dev/null and b/source_assets/icons/wrench.png differ diff --git a/source_assets/icons/wrench.xcf b/source_assets/icons/wrench.xcf new file mode 100644 index 0000000..9948960 Binary files /dev/null and b/source_assets/icons/wrench.xcf differ diff --git a/source_assets/ui/areas/canteen.png b/source_assets/ui/areas/canteen.png new file mode 100644 index 0000000..e3ee5e4 Binary files /dev/null and b/source_assets/ui/areas/canteen.png differ diff --git a/source_assets/ui/areas/command.png b/source_assets/ui/areas/command.png new file mode 100644 index 0000000..bf4b17e Binary files /dev/null and b/source_assets/ui/areas/command.png differ diff --git a/source_assets/ui/areas/engineering.png b/source_assets/ui/areas/engineering.png new file mode 100644 index 0000000..e80ed04 Binary files /dev/null and b/source_assets/ui/areas/engineering.png differ diff --git a/source_assets/ui/areas/engineering.xcf b/source_assets/ui/areas/engineering.xcf new file mode 100644 index 0000000..05b39a8 Binary files /dev/null and b/source_assets/ui/areas/engineering.xcf differ diff --git a/source_assets/ui/areas/reactor.png b/source_assets/ui/areas/reactor.png new file mode 100644 index 0000000..3ebce07 Binary files /dev/null and b/source_assets/ui/areas/reactor.png differ diff --git a/source_assets/ui/areas/reactor.xcf b/source_assets/ui/areas/reactor.xcf new file mode 100644 index 0000000..343d09b Binary files /dev/null and b/source_assets/ui/areas/reactor.xcf differ diff --git a/source_assets/ui/areas/science.png b/source_assets/ui/areas/science.png new file mode 100644 index 0000000..11f7283 Binary files /dev/null and b/source_assets/ui/areas/science.png differ diff --git a/source_assets/ui/areas/sixbay.png b/source_assets/ui/areas/sixbay.png new file mode 100644 index 0000000..09a005f Binary files /dev/null and b/source_assets/ui/areas/sixbay.png differ diff --git a/source_assets/ui/end_text_bg.png b/source_assets/ui/end_text_bg.png new file mode 100644 index 0000000..64586e9 Binary files /dev/null and b/source_assets/ui/end_text_bg.png differ diff --git a/source_assets/ui/end_text_bg.xcf b/source_assets/ui/end_text_bg.xcf new file mode 100644 index 0000000..0b9dfb6 Binary files /dev/null and b/source_assets/ui/end_text_bg.xcf differ diff --git a/source_assets/ui/help.xcf b/source_assets/ui/help.xcf new file mode 100644 index 0000000..9f2bdc0 Binary files /dev/null and b/source_assets/ui/help.xcf differ diff --git a/source_assets/ui/help_1.png b/source_assets/ui/help_1.png new file mode 100644 index 0000000..3cf9e04 Binary files /dev/null and b/source_assets/ui/help_1.png differ diff --git a/source_assets/ui/help_2.png b/source_assets/ui/help_2.png new file mode 100644 index 0000000..73a9776 Binary files /dev/null and b/source_assets/ui/help_2.png differ diff --git a/source_assets/ui/help_3.png b/source_assets/ui/help_3.png new file mode 100644 index 0000000..569a421 Binary files /dev/null and b/source_assets/ui/help_3.png differ diff --git a/source_assets/ui/help_4.png b/source_assets/ui/help_4.png new file mode 100644 index 0000000..3e92fc3 Binary files /dev/null and b/source_assets/ui/help_4.png differ diff --git a/source_assets/ui/ship.png b/source_assets/ui/ship.png new file mode 100644 index 0000000..dee34a5 Binary files /dev/null and b/source_assets/ui/ship.png differ diff --git a/source_assets/ui/shipxcf.xcf b/source_assets/ui/shipxcf.xcf new file mode 100644 index 0000000..9fefe01 Binary files /dev/null and b/source_assets/ui/shipxcf.xcf differ