From 3c25ddfab963b49fa713bf7252f12c285ff02094 Mon Sep 17 00:00:00 2001
From: Alan <alanjfogel@gmail.com>
Date: Fri, 31 Jan 2025 18:13:34 -0600
Subject: [PATCH] Added Mage piece & ranged attack for it

---
 .godot/editor/editor_layout.cfg               |  12 +-
 .godot/editor/filesystem_cache8               |  39 +++---
 .godot/editor/filesystem_update4              |   2 +
 ...state-c2a7af834e91ff64325daddf58e45dc0.cfg |   2 +-
 .godot/editor/project_metadata.cfg            |   4 +-
 .godot/editor/script_editor_cache.cfg         |  26 +++-
 .godot/global_script_class_cache.cfg          |   6 +
 .godot/uid_cache.bin                          | Bin 3232 -> 3311 bytes
 Assets/temp_assets/mage.png                   | Bin 0 -> 318 bytes
 Assets/temp_assets/mage.png.import            |  34 +++++
 scenes/Mage.tscn                              |  10 ++
 scripts/Mage.gd                               | 124 ++++++++++++++++++
 scripts/game.gd                               |  73 +++++++----
 13 files changed, 277 insertions(+), 55 deletions(-)
 create mode 100644 Assets/temp_assets/mage.png
 create mode 100644 Assets/temp_assets/mage.png.import
 create mode 100644 scenes/Mage.tscn
 create mode 100644 scripts/Mage.gd

diff --git a/.godot/editor/editor_layout.cfg b/.godot/editor/editor_layout.cfg
index d618a04..fd86f4d 100644
--- a/.godot/editor/editor_layout.cfg
+++ b/.godot/editor/editor_layout.cfg
@@ -25,17 +25,17 @@ dock_5="Inspector,Node,History"
 
 [EditorNode]
 
-open_scenes=PackedStringArray("res://scenes/game.tscn", "res://scenes/explosion.tscn", "res://scenes/Pawn.tscn", "res://scenes/Rook.tscn", "res://scenes/Bishop.tscn", "res://scenes/Queen.tscn", "res://scenes/King.tscn", "res://scenes/Knight.tscn", "res://scenes/Assassin.tscn")
-current_scene="res://scenes/Pawn.tscn"
-center_split_offset=-343
+open_scenes=PackedStringArray("res://scenes/game.tscn", "res://scenes/explosion.tscn", "res://scenes/Pawn.tscn", "res://scenes/Rook.tscn", "res://scenes/Bishop.tscn", "res://scenes/Queen.tscn", "res://scenes/King.tscn", "res://scenes/Knight.tscn", "res://scenes/Assassin.tscn", "res://scenes/Mage.tscn")
+current_scene="res://scenes/Mage.tscn"
+center_split_offset=-255
 selected_default_debugger_tab_idx=0
 selected_main_editor_idx=2
-selected_bottom_panel_item=1
+selected_bottom_panel_item=0
 
 [ScriptEditor]
 
-open_scripts=["res://scripts/Assassin.gd", "res://scripts/Bishop.gd", "res://scripts/game.gd", "res://scripts/King.gd", "res://scripts/Knight.gd", "res://scripts/Pawn.gd", "res://scripts/Piece.gd", "res://scripts/Queen.gd", "res://scripts/Rook.gd"]
-selected_script="res://scripts/Pawn.gd"
+open_scripts=["res://scripts/Assassin.gd", "res://scripts/Bishop.gd", "res://scripts/game.gd", "res://scripts/King.gd", "res://scripts/Knight.gd", "res://scripts/Mage.gd", "res://scripts/Pawn.gd", "res://scripts/Piece.gd", "res://scripts/Queen.gd", "res://scripts/Rook.gd"]
+selected_script="res://scripts/Mage.gd"
 open_help=[]
 script_split_offset=70
 list_split_offset=0
diff --git a/.godot/editor/filesystem_cache8 b/.godot/editor/filesystem_cache8
index ecfb357..f888296 100644
--- a/.godot/editor/filesystem_cache8
+++ b/.godot/editor/filesystem_cache8
@@ -30,17 +30,17 @@ White_knight.png::CompressedTexture2D::854350289879594279::1738358720::173836019
 White_Pawn.png::CompressedTexture2D::919180529085242722::1738358720::1738360196::1::::<><>::
 White_Queen.png::CompressedTexture2D::4902137832695542513::1738358720::1738360196::1::::<><>::
 White_rook.png::CompressedTexture2D::4194129281780453908::1738358720::1738360196::1::::<><>::
-::res://assets/shaders/::1738360772
-bg.gdshader::Shader::-1::1738360772::0::1::::<><>::
-color.gdshader::Shader::-1::1738360772::0::1::::<><>::
-shadow.gdshader::Shader::-1::1738360772::0::1::::<><>::
+::res://assets/shaders/::1738366873
+bg.gdshader::Shader::-1::1738366873::0::1::::<><>::
+color.gdshader::Shader::-1::1738366873::0::1::::<><>::
+shadow.gdshader::Shader::-1::1738366873::0::1::::<><>::
 ::res://assets/sprites/::1738360196
 bishop.png::CompressedTexture2D::4631301773944929250::1738358798::1738360196::1::::<><>::
 knight.png::CompressedTexture2D::3545640967717948854::1738358798::1738360196::1::::<><>::
 pawn.png::CompressedTexture2D::1338760335342038528::1738358798::1738360195::1::::<><>::
 rook.png::CompressedTexture2D::6790909281007670776::1738358798::1738360195::1::::<><>::
 tile.png::CompressedTexture2D::8704336058451696509::1738358570::1738360195::1::::<><>::
-::res://assets/temp_assets/::1738360998
+::res://assets/temp_assets/::1738367404
 assassin.png::CompressedTexture2D::2309680507621369322::1738360966::1738361001::1::::<><>::
 black_bishop.png::CompressedTexture2D::7509881182472568151::1738358720::1738360195::1::::<><>::
 black_king.png::CompressedTexture2D::3646032776351028361::1738358720::1738360195::1::::<><>::
@@ -48,6 +48,7 @@ black_knight.png::CompressedTexture2D::4591257172048987833::1738358720::17383601
 black_pawn.png::CompressedTexture2D::3912668014183198267::1738358720::1738360195::1::::<><>::
 black_queen.png::CompressedTexture2D::7989886812523566234::1738358720::1738360195::1::::<><>::
 black_rook.png::CompressedTexture2D::8767708966549765967::1738358720::1738360195::1::::<><>::
+mage.png::CompressedTexture2D::4650471376600460963::1738367395::1738367411::1::::<><>::
 Piece_move.png::CompressedTexture2D::260618725614842917::1738358720::1738360195::1::::<><>::
 temp_chess_board.png::CompressedTexture2D::4173558678901569366::1738358720::1738360195::1::::<><>::
 turn-black.png::CompressedTexture2D::7112033964315790810::1738358720::1738360195::1::::<><>::
@@ -62,24 +63,26 @@ white_rook.png::CompressedTexture2D::3317152307554436932::1738358720::1738360196
 Go_Save_The_King_Menu.jpg::CompressedTexture2D::7252735845995868232::1738358720::1738360196::1::::<><>::
 Mockup Gameplay Design.jpg::CompressedTexture2D::4859609684236806088::1738358720::1738360196::1::::<><>::
 Mockup Shop Design.jpg::CompressedTexture2D::8043055154093708922::1738358720::1738360196::1::::<><>::
-::res://scenes/::1738360772
-Bishop.tscn::PackedScene::2789588702038144760::1738360361::0::1::::<><>::res://scripts/Bishop.gd<>uid://b68o4mj7wcwvq::::res://assets/sprites/bishop.png
+::res://scenes/::1738366873
+Bishop.tscn::PackedScene::2789588702038144760::1738366872::0::1::::<><>::res://scripts/Bishop.gd<>uid://b68o4mj7wcwvq::::res://assets/sprites/bishop.png
 board.tscn::PackedScene::5124694183364421304::1738358720::0::1::::<><>::uid://b0px5wlrm0mb3::::res://assets/temp_assets/temp_chess_board.png<>res://scripts/board.gd
-explosion.tscn::PackedScene::69466253159940830::1738360361::0::1::::<><>::
-game.tscn::PackedScene::8577524005707705072::1738360772::0::1::::<><>::res://scripts/game.gd<>res://assets/shaders/bg.gdshader<>uid://yeqb8ndri7xp::::res://assets/noise/noise.tres<>uid://ceas3dsjeq4ge::::res://assets/noise/noise2.tres<>uid://m6ki73qfbp2s::::res://assets/noise/noise3.tres
-King.tscn::PackedScene::8277830396459966414::1738360361::0::1::::<><>::res://scripts/King.gd<>uid://cdogixbq8ay3t::::res://assets/Resized Chess Piece Assets/White_king.png
-Knight.tscn::PackedScene::5270730075267457303::1738360361::0::1::::<><>::res://scripts/Knight.gd<>uid://mf4a3jclbwih::::res://assets/Resized Chess Piece Assets/White_knight.png
-Pawn.tscn::PackedScene::3675784333675896641::1738360361::0::1::::<><>::res://scripts/Pawn.gd<>uid://ndi1e8thkonq::::res://assets/Resized Chess Piece Assets/White_Pawn.png
-Queen.tscn::PackedScene::7495869360053814603::1738360361::0::1::::<><>::res://scripts/Queen.gd<>uid://cb3vq168iyomb::::res://assets/Resized Chess Piece Assets/White_Queen.png
-Rook.tscn::PackedScene::9162401199636684468::1738360361::0::1::::<><>::uid://b00wxxfjk04ke::::res://assets/Resized Chess Piece Assets/White_rook.png
+explosion.tscn::PackedScene::69466253159940830::1738366872::0::1::::<><>::
+game.tscn::PackedScene::8577524005707705072::1738366872::0::1::::<><>::res://scripts/game.gd<>res://assets/shaders/bg.gdshader<>uid://yeqb8ndri7xp::::res://assets/noise/noise.tres<>uid://ceas3dsjeq4ge::::res://assets/noise/noise2.tres<>uid://m6ki73qfbp2s::::res://assets/noise/noise3.tres
+King.tscn::PackedScene::8277830396459966414::1738366872::0::1::::<><>::res://scripts/King.gd<>uid://cdogixbq8ay3t::::res://assets/Resized Chess Piece Assets/White_king.png
+Knight.tscn::PackedScene::5270730075267457303::1738366873::0::1::::<><>::res://scripts/Knight.gd<>uid://mf4a3jclbwih::::res://assets/Resized Chess Piece Assets/White_knight.png
+Pawn.tscn::PackedScene::3675784333675896641::1738366872::0::1::::<><>::res://scripts/Pawn.gd<>uid://ndi1e8thkonq::::res://assets/Resized Chess Piece Assets/White_Pawn.png
+Queen.tscn::PackedScene::7495869360053814603::1738366872::0::1::::<><>::res://scripts/Queen.gd<>uid://cb3vq168iyomb::::res://assets/Resized Chess Piece Assets/White_Queen.png
+Assassin.tscn::PackedScene::1241611789899982875::1738366873::0::1::::<><>::res://scripts/Assassin.gd<>uid://753dogr1moxe::::res://assets/temp_assets/assassin.png
+Rook.tscn::PackedScene::9162401199636684468::1738366872::0::1::::<><>::uid://b00wxxfjk04ke::::res://assets/Resized Chess Piece Assets/White_rook.png
 texture_holder.tscn::PackedScene::594714386286134588::1738358720::0::1::::<><>::
-::res://scripts/::1738360772
+::res://scripts/::1738367154
 Bishop.gd::GDScript::-1::1738358720::0::1::::Bishop<>Piece<>::
-game.gd::GDScript::-1::1738360892::0::1::::game<>Node<>::
 King.gd::GDScript::-1::1738358720::0::1::::King<>Piece<>::
 Knight.gd::GDScript::-1::1738358802::0::1::::Knight<>Piece<>::
-Pawn.gd::GDScript::-1::1738358802::0::1::::Pawn<>Piece<>::
+Pawn.gd::GDScript::-1::1738366967::0::1::::Pawn<>Piece<>::
 Piece.gd::GDScript::-1::1738358720::0::1::::Piece<>Node2D<>::
 Queen.gd::GDScript::-1::1738358720::0::1::::Queen<>Piece<>::
-Assassin.gd::GDScript::-1::1738360861::0::1::::Assassin<>Piece<>::
+Assassin.gd::GDScript::-1::1738361495::0::1::::Assassin<>Piece<>::
+game.gd::GDScript::-1::1738367020::0::1::::game<>Node<>::
+Mage.gd::GDScript::-1::1738367372::0::1::::Mage<>Piece<>::
 Rook.gd::GDScript::-1::1738358720::0::1::::Rook<>Piece<>::
diff --git a/.godot/editor/filesystem_update4 b/.godot/editor/filesystem_update4
index 1dd8b09..3c287f7 100644
--- a/.godot/editor/filesystem_update4
+++ b/.godot/editor/filesystem_update4
@@ -18,3 +18,5 @@ res://scripts/Assassin.gd
 res://scripts/game.gd
 res://scenes/Assassin.tscn
 res://scripts/Pawn.gd
+res://scripts/Mage.gd
+res://scenes/Mage.tscn
diff --git a/.godot/editor/game.tscn-editstate-c2a7af834e91ff64325daddf58e45dc0.cfg b/.godot/editor/game.tscn-editstate-c2a7af834e91ff64325daddf58e45dc0.cfg
index 2309a88..5ed3fa2 100644
--- a/.godot/editor/game.tscn-editstate-c2a7af834e91ff64325daddf58e45dc0.cfg
+++ b/.godot/editor/game.tscn-editstate-c2a7af834e91ff64325daddf58e45dc0.cfg
@@ -175,4 +175,4 @@ Anim={
 "zfar": 4000.01,
 "znear": 0.05
 }
-selected_nodes=Array[NodePath]([])
+selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@16886/@Panel@13/@VBoxContainer@14/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@25/DockVSplitCenter/@VSplitContainer@52/@VBoxContainer@53/@PanelContainer@98/MainScreen/@CanvasItemEditor@9272/@VSplitContainer@9094/@HSplitContainer@9096/@HSplitContainer@9098/@Control@9099/@SubViewportContainer@9100/@SubViewport@9101/Node2D")])
diff --git a/.godot/editor/project_metadata.cfg b/.godot/editor/project_metadata.cfg
index 0d8854a..4a2c8f2 100644
--- a/.godot/editor/project_metadata.cfg
+++ b/.godot/editor/project_metadata.cfg
@@ -13,8 +13,8 @@ last_selected_language="GDScript"
 
 [recent_files]
 
-scripts=["res://scripts/Assassin.gd", "res://scripts/Knight.gd", "res://scripts/King.gd", "res://scripts/Queen.gd", "res://scripts/Bishop.gd", "res://scripts/Rook.gd", "res://scripts/Pawn.gd", "res://scripts/Piece.gd", "@GDScript", "int"]
-scenes=["res://scenes/Assassin.tscn", "res://scenes/Knight.tscn", "res://scenes/King.tscn", "res://scenes/Queen.tscn", "res://scenes/Bishop.tscn", "res://scenes/Rook.tscn", "res://scenes/Pawn.tscn", "res://scenes/explosion.tscn", "res://scenes/game.tscn", "res://scenes/chess_board.tscn"]
+scripts=["res://scripts/Mage.gd", "res://scripts/Assassin.gd", "res://scripts/Knight.gd", "res://scripts/King.gd", "res://scripts/Queen.gd", "res://scripts/Bishop.gd", "res://scripts/Rook.gd", "res://scripts/Pawn.gd", "res://scripts/Piece.gd", "@GDScript"]
+scenes=["res://scenes/Mage.tscn", "res://scenes/Assassin.tscn", "res://scenes/Knight.tscn", "res://scenes/King.tscn", "res://scenes/Queen.tscn", "res://scenes/Bishop.tscn", "res://scenes/Rook.tscn", "res://scenes/Pawn.tscn", "res://scenes/explosion.tscn", "res://scenes/game.tscn"]
 
 [color_picker]
 
diff --git a/.godot/editor/script_editor_cache.cfg b/.godot/editor/script_editor_cache.cfg
index 95fc328..a5f5ca2 100644
--- a/.godot/editor/script_editor_cache.cfg
+++ b/.godot/editor/script_editor_cache.cfg
@@ -3,11 +3,11 @@
 state={
 "bookmarks": PackedInt32Array(),
 "breakpoints": PackedInt32Array(),
-"column": 53,
+"column": 22,
 "folded_lines": Array[int]([]),
 "h_scroll_position": 0,
-"row": 294,
-"scroll_position": 284.0,
+"row": 113,
+"scroll_position": 103.0,
 "selection": false,
 "syntax_highlighter": "GDScript"
 }
@@ -31,11 +31,11 @@ state={
 state={
 "bookmarks": PackedInt32Array(),
 "breakpoints": PackedInt32Array(),
-"column": 13,
+"column": 0,
 "folded_lines": Array[int]([]),
 "h_scroll_position": 0,
-"row": 89,
-"scroll_position": 70.0,
+"row": 51,
+"scroll_position": 41.0,
 "selection": false,
 "syntax_highlighter": "GDScript"
 }
@@ -123,3 +123,17 @@ state={
 "selection": false,
 "syntax_highlighter": "GDScript"
 }
+
+[res://scripts/Mage.gd]
+
+state={
+"bookmarks": PackedInt32Array(),
+"breakpoints": PackedInt32Array(),
+"column": 38,
+"folded_lines": Array[int]([]),
+"h_scroll_position": 0,
+"row": 113,
+"scroll_position": 99.0,
+"selection": false,
+"syntax_highlighter": "GDScript"
+}
diff --git a/.godot/global_script_class_cache.cfg b/.godot/global_script_class_cache.cfg
index b12ce8f..96438af 100644
--- a/.godot/global_script_class_cache.cfg
+++ b/.godot/global_script_class_cache.cfg
@@ -24,6 +24,12 @@ list=Array[Dictionary]([{
 "path": "res://scripts/Knight.gd"
 }, {
 "base": &"Piece",
+"class": &"Mage",
+"icon": "",
+"language": &"GDScript",
+"path": "res://scripts/Mage.gd"
+}, {
+"base": &"Piece",
 "class": &"Pawn",
 "icon": "",
 "language": &"GDScript",
diff --git a/.godot/uid_cache.bin b/.godot/uid_cache.bin
index 6e170e6b50b7f284327ca43d87a9f1cb4100c68a..1e23be115ed807ce4e7131fd708687be54e0a201 100644
GIT binary patch
delta 67
zcmZ1=`CgLIek0?29?r#iDKCUicRDCecI1%J%1um9)hozLH&nNtbZnangBSw?Ls4q6
VmA-y)a%x^`vA!=zK}m6P9smk<7Ks1=

delta 10
RcmaDaxj>T9b|d3_9sm_M16=?B

diff --git a/Assets/temp_assets/mage.png b/Assets/temp_assets/mage.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6b20a502f79f4fdb51ba26ea525a5808850d9a4
GIT binary patch
literal 318
zcmV-E0m1%>P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px#_(?=TR9J=WmQ50ZFbsuL#}mTn9c&NbcnI(gIOPV6M~e&XhM$s`wsyl?hvp-^
zyh2o2Cgovf=EZ@=Kxe7})|zV|Q~<H&D8wmebL$+LpCphf@rG{JmT4$y{x^s{0A}XF
zdk8{g6!d$(#*v7Ku5G(}ezYK$kzyMGt>M~u-_x|Hd-i>q9FR@~2_iTLati_o=8DNW
zr-l(}@IGq}sP2Nf8G{iK^CbZgEe(lY!$|;J+n|Afw;&d^#XS(-e7+6A1AW(h4=wRS
zg2r;OAClZUOAEu;FHIAzLxTu*?N$Z^X|kZIP}+yE?p^{w+8lzYK7m7rK4p{NYXV2K
QHvj+t07*qoM6N<$f(cuJ4*&oF

literal 0
HcmV?d00001

diff --git a/Assets/temp_assets/mage.png.import b/Assets/temp_assets/mage.png.import
new file mode 100644
index 0000000..d6399e4
--- /dev/null
+++ b/Assets/temp_assets/mage.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b7iyt4iwjbtd0"
+path="res://.godot/imported/mage.png-aa266229e8d4b8a7cd1dbb6644da4861.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/temp_assets/mage.png"
+dest_files=["res://.godot/imported/mage.png-aa266229e8d4b8a7cd1dbb6644da4861.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/scenes/Mage.tscn b/scenes/Mage.tscn
new file mode 100644
index 0000000..cfeb30c
--- /dev/null
+++ b/scenes/Mage.tscn
@@ -0,0 +1,10 @@
+[gd_scene load_steps=3 format=3 uid="uid://fag2130aog4"]
+
+[ext_resource type="Script" path="res://scripts/Mage.gd" id="1_o7lxu"]
+[ext_resource type="Texture2D" uid="uid://b7iyt4iwjbtd0" path="res://assets/temp_assets/mage.png" id="2_i5ela"]
+
+[node name="Node2D" type="Node2D"]
+script = ExtResource("1_o7lxu")
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+texture = ExtResource("2_i5ela")
diff --git a/scripts/Mage.gd b/scripts/Mage.gd
new file mode 100644
index 0000000..655d49a
--- /dev/null
+++ b/scripts/Mage.gd
@@ -0,0 +1,124 @@
+extends Piece
+
+class_name Mage
+
+enum Upgrade {
+	# Add any specific upgrades for Mage here
+}
+
+@onready var game = get_tree().root.get_node("Game")
+
+func _init(is_white: bool, position: Vector2):
+	super._init(is_white, position)
+
+func get_valid_moves(board_state: Array, pos: Vector2) -> Array[Vector2]:
+	var valid_moves: Array[Vector2] = []
+	var sel_x = pos.x
+	var sel_y = pos.y
+
+	# Add moves based on the provided logic
+	if (sel_x + 1) < 8 and (sel_y + 1) < 8:
+		if is_empty(board_state, sel_x + 1, sel_y + 1):
+			valid_moves.append(Vector2(sel_x + 1, sel_y + 1))
+	if (sel_x - 1) >= 0 and (sel_y + 1) < 8:
+		if is_empty(board_state, sel_x - 1, sel_y + 1):
+			valid_moves.append(Vector2(sel_x - 1, sel_y + 1))
+	if (sel_x + 1) < 8 and (sel_y - 1) >= 0:
+		if is_empty(board_state, sel_x + 1, sel_y - 1):
+			valid_moves.append(Vector2(sel_x + 1, sel_y - 1))
+	if (sel_x - 1) >= 0 and (sel_y - 1) >= 0:
+		if is_empty(board_state, sel_x - 1, sel_y - 1):
+			valid_moves.append(Vector2(sel_x - 1, sel_y - 1))
+
+	if (sel_x + 1) < 8:
+		if is_empty(board_state, sel_x + 1, sel_y):
+			valid_moves.append(Vector2(sel_x + 1, sel_y))
+	if (sel_x - 1) >= 0:
+		if is_empty(board_state, sel_x - 1, sel_y):
+			valid_moves.append(Vector2(sel_x - 1, sel_y))
+
+	if (sel_y + 1) < 8:
+		if is_empty(board_state, sel_x, sel_y + 1):
+			valid_moves.append(Vector2(sel_x, sel_y + 1))
+	if (sel_y - 1) >= 0:
+		if is_empty(board_state, sel_x, sel_y - 1):
+			valid_moves.append(Vector2(sel_x, sel_y - 1))
+
+	return valid_moves
+
+func get_valid_shots(board_state: Array, pos: Vector2) -> Array[Vector2]:
+	var valid_shots: Array[Vector2] = []
+	var sel_x = pos.x
+	var sel_y = pos.y
+
+	# Valid shots diagonally down and right
+	for x in range(1, 8):
+		var new_x = sel_x + x
+		var new_y = sel_y + x
+		if new_x < 8 and new_y < 8:
+			if is_empty(board_state, new_x, new_y):
+				pass
+			elif is_opposite(board_state, new_x, new_y):
+				valid_shots.append(Vector2(new_x, new_y))
+				break
+			else:
+				break
+		else:
+			break
+
+	# Repeat for diagonally up and left
+	for x in range(1, 8):
+		var new_x = sel_x - x
+		var new_y = sel_y - x
+		if new_x >= 0 and new_y >= 0:
+			if is_empty(board_state, new_x, new_y):
+				pass
+			elif is_opposite(board_state, new_x, new_y):
+				valid_shots.append(Vector2(new_x, new_y))
+				break
+			else:
+				break
+		else:
+			break
+
+	# Repeat for diagonally down and left
+	for x in range(1, 8):
+		var new_x = sel_x - x
+		var new_y = sel_y + x
+		if new_x >= 0 and new_y < 8:
+			if is_empty(board_state, new_x, new_y):
+				pass
+			elif is_opposite(board_state, new_x, new_y):
+				valid_shots.append(Vector2(new_x, new_y))
+				break
+			else:
+				break
+		else:
+			break
+
+	# Repeat for diagonally up and right
+	for x in range(1, 8):
+		var new_x = sel_x + x
+		var new_y = sel_y - x
+		if new_x < 8 and new_y >= 0:
+			if is_empty(board_state, new_x, new_y):
+				pass
+			elif is_opposite(board_state, new_x, new_y):
+				valid_shots.append(Vector2(new_x, new_y))
+				break
+			else:
+				break
+		else:
+			break
+
+	return valid_shots
+
+func shoot_projectile(x: int, y: int):
+	game.shoot_projectile(x, y)
+
+func is_empty(board_state: Array, x: int, y: int) -> bool:
+	return board_state[x][y] == null
+
+func is_opposite(board_state: Array, x: int, y: int) -> bool:
+	return board_state[x][y] != null and board_state[x][y].is_white != is_white
+	
diff --git a/scripts/game.gd b/scripts/game.gd
index a8f0912..f416dc6 100644
--- a/scripts/game.gd
+++ b/scripts/game.gd
@@ -56,6 +56,7 @@ func _ready() -> void:
 	board[4][2] = Pawn.new(true, Vector2(4, 7))
 	board[5][7] = Knight.new(true, Vector2(5, 7))
 	board[6][7] = Assassin.new(true, Vector2(6, 7))
+	board[7][6] = Mage.new(true, Vector2(7, 6))
 	board[7][7] = Rook.new(true, Vector2(7, 7))
 
 	board[0][4] = Rook.new(false, Vector2(0, 4))
@@ -64,7 +65,7 @@ func _ready() -> void:
 	board[3][5] = Pawn.new(false, Vector2(3, 5))
 	board[4][4] = Assassin.new(false, Vector2(4, 4))
 	board[3][4] = Pawn.new(false, Vector2(3, 4))
-	board[4][3] = Pawn.new(false, Vector2(4, 3))
+	board[4][3] = Mage.new(false, Vector2(4, 3))
 	board[7][5] = Rook.new(false, Vector2(7, 5))
 	
 	#potential 'holes', not quite working yet
@@ -140,6 +141,8 @@ func draw_pieces():
 					piece_scene = preload("res://scenes/Knight.tscn")
 				elif board[x][y] is Assassin:
 					piece_scene = preload("res://scenes/Assassin.tscn")
+				elif board[x][y] is Mage:
+					piece_scene = preload("res://scenes/Mage.tscn")
 				
 				if piece_scene:
 					var piece_instance = piece_scene.instantiate()
@@ -364,7 +367,12 @@ func unselect_piece():
 func highlight_tiles():
 	# Clear the previously selected valid moves
 	remove_highlight()
-	valid_moves = selected_piece_value.get_valid_moves(board, selected_piece_position)
+	if selected_piece_value is Mage:
+		valid_moves = selected_piece_value.get_valid_moves(board, selected_piece_position)
+		valid_moves += selected_piece_value.get_valid_shots(board, selected_piece_position)
+	else:
+		valid_moves = selected_piece_value.get_valid_moves(board, selected_piece_position)
+
 
 	for child in tile_container.get_children():
 		if child.position / tile_size in valid_moves:
@@ -387,36 +395,57 @@ func move_selected_piece(x,y):
 	if selected_piece != null:
 		#can only move to tiles in valid_moves
 		if Vector2(x,y) in valid_moves:
-			#if tile has opponent piece, remove piece
-			if is_opponent(x,y):
-				remove_piece(x,y)
 			
+			if selected_piece_value is Mage:
+				if abs(selected_piece_position.x - x) <= 1 and abs(selected_piece_position.y - y) <= 1:
+					if is_empty(x, y):
+						move_piece(x, y)
+					else:
+						unselect_piece()
+				else:	
+					shoot_projectile(x, y)
+
 			# check for if assassin is moving behind the opponent's pieces
-			if selected_piece_value is Assassin:
+			elif selected_piece_value is Assassin:
 				if selected_piece_value.is_white:
 					if is_opponent(x, y + 1):
 						remove_piece(x, y + 1)
 				else:
 					if is_opponent(x, y - 1):
 						remove_piece(x, y - 1)
+				move_piece(x, y)
 
+			else:
+				move_piece(x, y)
+		else:
+			unselect_piece()
+	remove_highlight()
 
-			#clear the selected_piece's previous position
-			board[selected_piece_position.x][selected_piece_position.y] = null
+func move_piece(x, y):
+	# If tile has opponent piece, remove piece
+	if is_opponent(x, y):
+		remove_piece(x, y)
 
-			board[x][y] = selected_piece_value
+	# Clear the selected_piece's previous position
+	board[selected_piece_position.x][selected_piece_position.y] = null
 
+	# Update the board with the new position
+	board[x][y] = selected_piece_value
 
-			#update selected_piece's screen coordinate position
-			selected_piece_position = Vector2((x*tile_size)+ tile_size/2, (y*tile_size) + tile_size/2)
-			
-			target_position = selected_piece_position
-			moving = true
-			valid_moves = []
-			
-		
-		else:
-			unselect_piece()
-		
-	remove_highlight()
-		
+	# Update selected_piece's screen coordinate position
+	selected_piece_position = Vector2((x * tile_size) + tile_size / 2, (y * tile_size) + tile_size / 2)
+
+	target_position = selected_piece_position
+	moving = true
+	valid_moves = []
+
+func shoot_projectile(x: int, y: int):
+	remove_piece(x, y)
+	board[x][y] = null
+	unselect_piece()
+
+	explosion_effect.color = Color(1, 0, 1)
+	explosion_effect.position = Vector2(x, y) * tile_size + translate() + Vector2(tile_size / 2, tile_size / 2)
+	explosion_effect.restart()
+
+	# player_turn = !player_turn
-- 
GitLab