diff --git a/TODO.md b/TODO.md index c64e029..ee39daa 100644 --- a/TODO.md +++ b/TODO.md @@ -3,9 +3,7 @@ * +health, +attack, +speed, +jump, (pawn only) remove "attack_only", spawn a new (random?) piece, change movement type * then the enemy respawns units, their new units are stronger * support for pieces with multiple hit points - * unit info panel 2. Visual polish - * clean up tile borders * multiple square tiles to add variation * make the help text indicate (flash, etc.) 3. Sound effects diff --git a/assets/export/attack.png b/assets/export/attack.png new file mode 100644 index 0000000..45c4779 Binary files /dev/null and b/assets/export/attack.png differ diff --git a/assets/export/edge.png b/assets/export/edge.png index 23fbaf9..45c88aa 100644 Binary files a/assets/export/edge.png and b/assets/export/edge.png differ diff --git a/assets/export/end_song.wav b/assets/export/end_song.wav new file mode 100644 index 0000000..59910ba Binary files /dev/null and b/assets/export/end_song.wav differ diff --git a/assets/export/health.png b/assets/export/health.png new file mode 100644 index 0000000..2c2860b Binary files /dev/null and b/assets/export/health.png differ diff --git a/assets/export/kills.png b/assets/export/kills.png new file mode 100644 index 0000000..df32dff Binary files /dev/null and b/assets/export/kills.png differ diff --git a/assets/export/movement.png b/assets/export/movement.png new file mode 100644 index 0000000..508583f Binary files /dev/null and b/assets/export/movement.png differ diff --git a/assets/source/buttons.xcf b/assets/source/buttons.xcf index 208b44b..47a2539 100644 Binary files a/assets/source/buttons.xcf and b/assets/source/buttons.xcf differ diff --git a/src/EndMenu.tscn b/src/EndMenu.tscn index 227154c..2ac10c3 100644 --- a/src/EndMenu.tscn +++ b/src/EndMenu.tscn @@ -51,3 +51,13 @@ margin_right = 688.0 margin_bottom = 116.0 custom_fonts/font = SubResource( 2 ) text = "Quit" + +[node name="Fail Game" type="Button" parent="VBoxContainer"] +margin_right = 12.0 +margin_bottom = 20.0 +text = "Fail Game" + +[node name="Win Game" type="Button" parent="VBoxContainer"] +margin_right = 12.0 +margin_bottom = 20.0 +text = "Win Game" diff --git a/src/Game.gd b/src/Game.gd index d565e9d..e1381db 100644 --- a/src/Game.gd +++ b/src/Game.gd @@ -99,6 +99,7 @@ func _on_hold_start(piece, event): func _on_hold_stop(piece, event): if self.selected_piece != null: # deselect + get_node("/root/Game/PanelRight/VBox/PieceInfo").set_visible(false) var p = self.selected_piece if p.is_in_group("player"): p.get_node("Body").set_modulate(Color(1, 1, 1, 1)) @@ -164,6 +165,7 @@ func pieces_hostile(p1, p2): func _on_piece_click(piece, event): if self.selected_piece != null: # deselect + get_node("/root/Game/PanelRight/VBox/PieceInfo").set_visible(false) var p = self.selected_piece if p.is_in_group("player"): p.get_node("Body").set_modulate(Color(1, 1, 1, 1)) @@ -186,6 +188,8 @@ func _on_piece_click(piece, event): var square = square_of_piece(piece) var moves = get_valid_piece_moves(piece) set_square_hilights_for_moves(moves) + get_node("/root/Game/PanelRight/VBox/PieceInfo").set_piece_info(piece) + get_node("/root/Game/PanelRight/VBox/PieceInfo").set_visible(true) func clear_square_hilights_for_moves(moves): var pf = get_node("/root/Game/MarginContainer/Playfield") @@ -253,6 +257,8 @@ func _ready(): get_node("/root/Game/EndMenu/VBoxContainer/New").connect("pressed", self, "_on_new_game_pressed") get_node("/root/Game/EndMenu/VBoxContainer/Quit").connect("pressed", self, "_on_quit_game_pressed") + get_node("/root/Game/EndMenu/VBoxContainer/Fail Game").connect("pressed", self, "_on_fail_game") + get_node("/root/Game/EndMenu/VBoxContainer/Win Game").connect("pressed", self, "_on_win_game") reset_game_state() func _input(ev): @@ -436,8 +442,32 @@ func _on_new_turn(): get_node("TopBar/Top/HBoxContainer/Turn").set_text(str(self.turn)) func _reset_help(): - get_node("BottomBar/Help").set_text("Delay losing as long as possible. Your loss is inevitable.\nClick on piece to see it's possible moves and stats.\nDrag and drop a piece to make a move.") + get_node("BottomBar/Help").set_text("Delay losing as long as possible. Your will lose.\nClick on piece to see it's possible moves and stats.\nDrag and drop a piece to make a move.") +func _on_game_end(force_condition = null): + get_node("/root/Game/TopBar/Bottom/Instruction").set_text("Game over") + self.current_state = 99 + var player_victory = false + if force_condition == null: + if get_tree().get_nodes_in_group("opponent").empty(): + player_victory = true + else: + player_victory = force_condition + if not player_victory: + get_node("/root/Game/EndSong").play() + get_node("/root/Game/BottomBar/Help").set_text("Unsurprisingly, the result was known before-hand.") + else: + get_node("/root/Game/BottomBar/Help").set_text("Well, I'll be damned. I didn't think this would happen!") + get_node("/root/Game/Impossible").play() + # Show a popup for new one, or quit + self._on_escape(true, "Game over!") + +func _on_fail_game(): + _on_game_end(false) + +func _on_win_game(): + _on_game_end(true) + # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): if self.flash_help != null: @@ -447,21 +477,9 @@ func _process(delta): self._reset_help() self.flash_help = null var opponent_pieces = get_tree().get_nodes_in_group("opponent") - if opponent_pieces.empty() or get_tree().get_nodes_in_group("player").empty(): + if opponent_pieces.empty() or get_tree().get_nodes_in_group("player").empty() and self.current_state != 99: # The game is over - self.current_state = 99 - var player_victory = false - if get_tree().get_nodes_in_group("opponent").empty(): - player_victory = true - get_node("/root/Game/TopBar/Bottom/Instruction").set_text("Game over") - if not player_victory: - get_node("/root/Game/EndSong").play() - get_node("/root/Game/BottomBar/Help").set_text("Unsurprisingly, the result was known before-hand.") - else: - get_node("/root/Game/BottomBar/Help").set_text("Well, I'll be damned. I didn't think this would happen!") - get_node("/root/Game/Impossible").play() - # Show a popup for new one, or quit - self._on_escape(true, "Game over!") + self._on_game_end() if self.current_state == 1: if self.ai_target != null: var target_square = self.board_squares[self.ai_target] @@ -475,9 +493,12 @@ func _process(delta): ) else: # End movement + var square = square_of_piece(self.ai_piece) if target_square['piece'] != null: # @TODO If the target doesn't die, we need to bounce back target_square['piece'].queue_free() + square['piece'].kills += 1 + get_node("PanelRight/VBox/PieceInfo").set_piece_info(square['piece']) var c = self.rng.randi() % 100 var index_to_play = null for idx in self.on_player_lose_piece.keys(): @@ -487,7 +508,6 @@ func _process(delta): if index_to_play != null: print("ai loss Chance to play: ", c, " got index ", index_to_play) get_node(self.on_player_lose_piece[index_to_play]).play() - var square = square_of_piece(self.ai_piece) square['piece'] = null target_square['piece'] = self.ai_piece self.ai_piece.set_position(Vector2(target_square['x']*128, target_square['y']*128)) @@ -560,6 +580,8 @@ func _physics_process(delta): if dest_square['piece'] != null: # @TODO If the target doesn't die, we need to bounce back dest_square['piece'].queue_free() + square['piece'].kills += 1 + get_node("PanelRight/VBox/PieceInfo").set_piece_info(square['piece']) var c = self.rng.randi() % 100 var index_to_play = null for idx in self.on_ai_lose_piece.keys(): diff --git a/src/Game.tscn b/src/Game.tscn index 416c122..bf8a13f 100644 --- a/src/Game.tscn +++ b/src/Game.tscn @@ -1,11 +1,11 @@ -[gd_scene load_steps=20 format=2] +[gd_scene load_steps=21 format=2] [ext_resource path="res://src/Game.gd" type="Script" id=1] [ext_resource path="res://src/Playfield.tscn" type="PackedScene" id=2] [ext_resource path="res://src/large font.tres" type="DynamicFont" id=3] [ext_resource path="res://assets/source/Bitstream Vera Sans Mono Bold Nerd Font Complete.ttf" type="DynamicFontData" id=4] [ext_resource path="res://src/EndMenu.tscn" type="PackedScene" id=5] -[ext_resource path="res://assets/export/end_song.ogg" type="AudioStream" id=6] +[ext_resource path="res://assets/export/end_song.wav" type="AudioStream" id=6] [ext_resource path="res://assets/export/impossible.wav" type="AudioStream" id=7] [ext_resource path="res://assets/export/thinkyoucan.wav" type="AudioStream" id=8] [ext_resource path="res://assets/export/yammering.wav" type="AudioStream" id=9] @@ -17,6 +17,7 @@ [ext_resource path="res://assets/export/skip_pressed.png" type="Texture" id=15] [ext_resource path="res://assets/export/skip_disabled.png" type="Texture" id=16] [ext_resource path="res://assets/export/skip_hover.png" type="Texture" id=17] +[ext_resource path="res://src/PieceDetails.tscn" type="PackedScene" id=18] [sub_resource type="DynamicFont" id=1] size = 24 @@ -115,7 +116,6 @@ valign = 1 [node name="EndSong" type="AudioStreamPlayer" parent="."] stream = ExtResource( 6 ) -volume_db = 4.0 autoplay = true [node name="Yammering" type="AudioStreamPlayer" parent="."] @@ -142,7 +142,7 @@ stream = ExtResource( 10 ) [node name="PanelRight" type="Panel" parent="."] anchor_right = 1.0 anchor_bottom = 1.0 -margin_left = 1024.0 +margin_left = 1036.0 [node name="VBox" type="VBoxContainer" parent="PanelRight"] anchor_right = 1.0 @@ -156,13 +156,13 @@ __meta__ = { } [node name="HBox" type="HBoxContainer" parent="PanelRight/VBox"] -margin_right = 226.0 +margin_right = 214.0 margin_bottom = 87.0 alignment = 2 [node name="VBox" type="VBoxContainer" parent="PanelRight/VBox/HBox"] -margin_left = 136.0 -margin_right = 226.0 +margin_left = 124.0 +margin_right = 214.0 margin_bottom = 87.0 alignment = 1 @@ -190,6 +190,18 @@ custom_fonts/font = SubResource( 2 ) text = "Skip Turn" align = 1 valign = 1 + +[node name="PieceInfo" parent="PanelRight/VBox" instance=ExtResource( 18 )] +visible = false +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 91.0 +margin_right = 214.0 +margin_bottom = 91.0 + +[node name="PanelLeft" type="Panel" parent="."] +margin_right = 240.0 +margin_bottom = 1024.0 [connection signal="finished" from="EndSong" to="." method="_on_EndSong_finished"] [connection signal="finished" from="Yammering" to="." method="_on_Yammering_finished"] [connection signal="finished" from="Dust" to="." method="_on_Dust_finished"] diff --git a/src/Piece.gd b/src/Piece.gd index b5bdff7..42b974b 100644 --- a/src/Piece.gd +++ b/src/Piece.gd @@ -76,7 +76,7 @@ func init_move_dict(position): "attack": true, "pos": position, "attack_only": false, - "jump": false, + "jump": self.jump, "source": self, } return x diff --git a/src/PieceDetails.gd b/src/PieceDetails.gd new file mode 100644 index 0000000..3578977 --- /dev/null +++ b/src/PieceDetails.gd @@ -0,0 +1,20 @@ +extends Control + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + +func set_piece_info(piece): + get_node("Vbox/Damage/Label").set_text(str(piece.damage)) + get_node("Vbox/Movement/Label").set_text(str(piece.speed)) + get_node("Vbox/Health/Label").set_text(str(piece.health)) + get_node("Vbox/Kills/Label").set_text(str(piece.kills)) +# Called every frame. 'delta' is the elapsed time since the previous frame. +#func _process(delta): +# pass diff --git a/src/PieceDetails.tscn b/src/PieceDetails.tscn new file mode 100644 index 0000000..702d098 --- /dev/null +++ b/src/PieceDetails.tscn @@ -0,0 +1,108 @@ +[gd_scene load_steps=8 format=2] + +[ext_resource path="res://src/font_32.tres" type="DynamicFont" id=1] +[ext_resource path="res://assets/export/health.png" type="Texture" id=2] +[ext_resource path="res://src/black_hilight_2px.tres" type="Material" id=3] +[ext_resource path="res://assets/export/movement.png" type="Texture" id=4] +[ext_resource path="res://assets/export/attack.png" type="Texture" id=5] +[ext_resource path="res://assets/export/kills.png" type="Texture" id=6] +[ext_resource path="res://src/PieceDetails.gd" type="Script" id=7] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 7 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Vbox" type="VBoxContainer" parent="."] +margin_right = 40.0 +margin_bottom = 40.0 + +[node name="Label" type="Label" parent="Vbox"] +margin_right = 190.0 +margin_bottom = 79.0 +custom_fonts/font = ExtResource( 1 ) +text = "Piece info +" + +[node name="Movement" type="HBoxContainer" parent="Vbox"] +margin_top = 83.0 +margin_right = 190.0 +margin_bottom = 147.0 + +[node name="TextureRect" type="TextureRect" parent="Vbox/Movement"] +material = ExtResource( 3 ) +margin_right = 64.0 +margin_bottom = 64.0 +hint_tooltip = "Movement" +texture = ExtResource( 4 ) + +[node name="Label" type="Label" parent="Vbox/Movement"] +margin_left = 68.0 +margin_top = 13.0 +margin_right = 87.0 +margin_bottom = 51.0 +custom_fonts/font = ExtResource( 1 ) +text = "1 " +__meta__ = { +"_editor_description_": "" +} + +[node name="Health" type="HBoxContainer" parent="Vbox"] +margin_top = 151.0 +margin_right = 190.0 +margin_bottom = 215.0 + +[node name="TextureRect" type="TextureRect" parent="Vbox/Health"] +material = ExtResource( 3 ) +margin_right = 64.0 +margin_bottom = 64.0 +texture = ExtResource( 2 ) + +[node name="Label" type="Label" parent="Vbox/Health"] +margin_left = 68.0 +margin_top = 13.0 +margin_right = 87.0 +margin_bottom = 51.0 +custom_fonts/font = ExtResource( 1 ) +text = "1 " + +[node name="Damage" type="HBoxContainer" parent="Vbox"] +margin_top = 219.0 +margin_right = 190.0 +margin_bottom = 283.0 + +[node name="TextureRect" type="TextureRect" parent="Vbox/Damage"] +material = ExtResource( 3 ) +margin_right = 64.0 +margin_bottom = 64.0 +texture = ExtResource( 5 ) + +[node name="Label" type="Label" parent="Vbox/Damage"] +margin_left = 68.0 +margin_top = 13.0 +margin_right = 87.0 +margin_bottom = 51.0 +custom_fonts/font = ExtResource( 1 ) +text = "1" + +[node name="Kills" type="HBoxContainer" parent="Vbox"] +margin_top = 287.0 +margin_right = 190.0 +margin_bottom = 351.0 + +[node name="TextureRect" type="TextureRect" parent="Vbox/Kills"] +material = ExtResource( 3 ) +margin_right = 64.0 +margin_bottom = 64.0 +texture = ExtResource( 6 ) + +[node name="Label" type="Label" parent="Vbox/Kills"] +margin_left = 68.0 +margin_top = 13.0 +margin_right = 87.0 +margin_bottom = 51.0 +custom_fonts/font = ExtResource( 1 ) +text = "1" diff --git a/src/Square.tscn b/src/Square.tscn index 3828a1a..080b6e1 100644 --- a/src/Square.tscn +++ b/src/Square.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://assets/export/square_edge.png" type="Texture" id=1] +[ext_resource path="res://assets/export/edge.png" type="Texture" id=1] [ext_resource path="res://assets/export/square_center_0.png" type="Texture" id=2] [ext_resource path="res://src/Square.gd" type="Script" id=3] diff --git a/src/black_hilight_2px.tres b/src/black_hilight_2px.tres new file mode 100644 index 0000000..2c6c3b6 --- /dev/null +++ b/src/black_hilight_2px.tres @@ -0,0 +1,8 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=2] + +[ext_resource path="res://src/hilight.shader" type="Shader" id=1] + +[resource] +shader = ExtResource( 1 ) +shader_param/width = 2.0 +shader_param/color = null diff --git a/src/font_32.tres b/src/font_32.tres new file mode 100644 index 0000000..a5f1fbe --- /dev/null +++ b/src/font_32.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/source/Bitstream Vera Sans Mono Bold Nerd Font Complete.ttf" type="DynamicFontData" id=1] + +[resource] +size = 32 +font_data = ExtResource( 1 ) diff --git a/src/pieces/Knight.gd b/src/pieces/Knight.gd index 61dcb8b..7d8b78e 100644 --- a/src/pieces/Knight.gd +++ b/src/pieces/Knight.gd @@ -9,6 +9,7 @@ extends Piece # Called when the node enters the scene tree for the first time. func _ready(): self.speed = 1 + self.jump = true func get_possible_moves(position): var directions = [ @@ -29,7 +30,6 @@ func get_possible_moves(position): var opt = self.init_move_dict( Vector2(position.x+(d.x*i), position.y+(d.y)*i) ) - opt.jump = true d_opts.append(opt) i += 1 options.append(d_opts)