Compare commits

..

23 Commits

Author SHA1 Message Date
admin bfcd48e657 think i finally solved movement going into enemy territory 2026-07-05 02:51:09 -04:00
admin dbafefd660 still working out movement 2026-07-04 03:04:56 -04:00
admin 336b72e4cb continuing to switch to MapCell orientation 2026-07-03 02:16:29 -04:00
admin e6355167e3 continuing to set up map and pegs 2026-07-02 22:50:21 -04:00
admin 0231c9d136 minor change for testing, still a bunch to do. someh=thing that popped up, should hostile and friendly pegs go at the same time or staggered 2026-07-02 03:51:22 -04:00
admin cbdca6f3cb implemented more code for adding more pegs, but still a lot of work to do on pathfinding, targeting, map etc. 2026-07-02 03:15:15 -04:00
admin 909f466f92 starting to build out more actions and pegs, first thing to do tho is rework movement / targeting a little bit 2026-07-02 00:20:52 -04:00
admin bbe9eefcfa minor changes, next step is to add 2-3 friendly pegs, 2 neutral pegs, 2 hostile pegs, 2 buildings and all associated actions for these additions 2026-07-01 02:36:31 -04:00
admin 2c289333f0 small change 2026-06-30 18:25:28 -04:00
admin b1625b15a0 implemented visibility, so pegs can only scope out as far as they can see. 2026-06-30 18:24:11 -04:00
admin c8e81e4f48 moved bucket to the playercontroller, changed tweenStages to a list of pegactions, so processtween takes in actions and builds off of that so that movement/actions priority will line up properly. change tweenstages key to be priority:loop. added category to actions to divide into movement vs action 2026-06-30 02:46:00 -04:00
admin 982c3e6786 added friendly and neutral peg, added disposition 2026-06-29 18:11:28 -04:00
admin ebdff1b200 undergoing a shift to change movement into another action that a peg can perform and giving pegs a list of actions order by priority 2026-06-29 02:43:25 -04:00
admin f6c54e0730 some formatting - note, i need to still fix attacks not starting / ending in the right spot, since an attack might be initiated from one cell then called while peg is at another cell 2026-06-26 16:46:16 -04:00
admin 2529d01ff4 cleared up issue with pathing, but still an issue with attacks? 2026-06-26 02:52:08 -04:00
admin 350d2bc4d1 adding in some example pegs and their actions. organizing folders, still working on pathing for some reason it won't move sometimes, and causes the looping to break 2026-06-26 02:36:01 -04:00
admin fc32baa071 switching up some more clicking 2026-06-25 18:11:43 -04:00
admin 37da9a4e84 altering enemies into peg to open up for the future with hostile and friendly pegs. made some changes to the pathfinding. starting to add a mouse handler that will more easily handle single and double clicks, and holds. Enemy controller becomes peg controller and will handle all peg interactions 2026-06-25 16:31:13 -04:00
admin e3cb4ef7ac fixed earlier problem 2026-06-25 03:29:46 -04:00
admin 61539e9250 still updating enemy movement and pathing and tweening 2026-06-25 03:14:21 -04:00
admin 98ca292901 still attempting to allow enemies to handle their own animations. still a matter of improving performance and there's some issue when enemies reach rank 0? 2026-06-24 03:00:23 -04:00
admin 8ae8ec3e58 trying out enemy animation again 2026-06-24 00:13:05 -04:00
admin 6af5f248ed finishing revert to older version 2026-06-24 00:09:17 -04:00
77 changed files with 1461 additions and 511 deletions
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://m4wfj36twmqy"
path="res://.godot/imported/attack.png-c625624f48e39eb3c9d0bdfb20bcabb8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Art/attack.png"
dest_files=["res://.godot/imported/attack.png-c625624f48e39eb3c9d0bdfb20bcabb8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c5jj7yhlnodxt"
path="res://.godot/imported/star.png-7953868fbd7392e6e06ff69587708912.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Art/star.png"
dest_files=["res://.godot/imported/star.png-7953868fbd7392e6e06ff69587708912.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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
+13 -17
View File
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Godot;
public partial class Attack : RigidBody2D
public partial class Ball : RigidBody2D
{
[Signal]
public delegate void HitEventHandler(Node NODE);
@@ -9,7 +9,7 @@ public partial class Attack : RigidBody2D
public delegate void BucketEnteredEventHandler();
public bool _hovered = false;
public int _damage = 1;
public int _healthChange = -1, _hits = 0;
public Vector2 _speed;
public Path2D _predictionPath;
public Commander _commanderOwner;
@@ -21,6 +21,16 @@ public partial class Attack : RigidBody2D
_predictionPath = GetNode<Path2D>("PredictedPath");
}
public void Act(Node BODY)
{
EmitSignal(SignalName.Hit, BODY);
if (BODY is Peg peg)
{
peg.ChangeHealth(_healthChange);
_hits++;
}
}
public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);
@@ -49,19 +59,5 @@ public partial class Attack : RigidBody2D
GravityScale = 1;
}
public void TakeAction(Node BODY)
{
EmitSignal(SignalName.Hit, BODY);
if (BODY is Enemy enemy)
{
enemy.TakeDamage(_damage, _commanderOwner);
}
}
public void OnMouseEntered(){
_hovered = true;
}
public void OnMouseExited(){
_hovered = true;
}
}
View File
+4 -4
View File
@@ -5,7 +5,7 @@ public partial class Bucket : Node2D
{
[Signal]
public delegate void AttackEnteredEventHandler(Attack ATTACK);
public delegate void BallEnteredEventHandler(Ball BALL);
public int _minX = -500, _maxX = 500, _movementSign = 1, _movementSpeed = 3;
public Vector2 _startPoisition;
@@ -27,10 +27,10 @@ public partial class Bucket : Node2D
}
public void OnBodyEntered(Node2D BODY)
{
if (BODY is Attack attack)
if (BODY is Ball ball)
{
EmitSignal(SignalName.AttackEntered, attack);
attack.EnteredBucket();
EmitSignal(SignalName.BallEntered, ball);
ball.EnteredBucket();
}
}
}
+20 -20
View File
@@ -6,18 +6,18 @@ public partial class Commander : Sprite2D
[Signal]
public delegate void ActionsUpEventHandler();
public int _actionsMax = 1, _actions;
public PackedScene _attackScene = GD.Load<PackedScene>("res://Attack.tscn");
public Attack _attack;
public PackedScene _ballScene = GD.Load<PackedScene>("res://Ball.tscn");
public Ball _ball;
public PlayerController _playerController;
public override void _Process(double delta)
{
base._Process(delta);
if (_attack != null)
if (_ball != null)
{
if (_attack.Position.Y > GetViewportRect().Size.Y + 50)
if (_ball.Position.Y > GetViewportRect().Size.Y + 50)
{
UnloadAttack();
UnloadBall();
if (_actions <= 0)
{
EmitSignal(SignalName.ActionsUp);
@@ -26,34 +26,34 @@ public partial class Commander : Sprite2D
}
}
public void AttackEnteredBucket()
public void BallEnteredBucket()
{
_actions += (_actions + 1) > _actionsMax ? 0 : 1;
UnloadAttack();
UnloadBall();
}
public void LoadAttack(Vector2 OFFSET)
public void LoadBall(Vector2 OFFSET)
{
if (_attack == null)
if (_ball == null)
{
_attack = _attackScene.Instantiate<Attack>();
_attack.Position = OFFSET;
_attack._commanderOwner = this;
_attack.GravityScale = 0;
_attack.BucketEntered += AttackEnteredBucket;
AddChild(_attack);
_ball = _ballScene.Instantiate<Ball>();
_ball.Position = OFFSET;
_ball._commanderOwner = this;
_ball.GravityScale = 0;
_ball.BucketEntered += BallEnteredBucket;
AddChild(_ball);
}
}
public void ShootCurrentAttack(Vector2 FORCE){
public void ShootCurrentBall(Vector2 FORCE){
_attack.Shoot(FORCE);
_ball.Shoot(FORCE);
_actions--;
}
public void UnloadAttack()
public void UnloadBall()
{
_attack.QueueFree();
_attack = null;
_ball.QueueFree();
_ball = null;
}
}
-113
View File
@@ -1,113 +0,0 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class Enemy : StaticBody2D
{
[Signal]
public delegate void DeathEventHandler(Enemy THIS);
[Signal]
public delegate void ClickedEventHandler(Enemy THIS);
[Signal]
public delegate void RightClickedEventHandler(Enemy THIS);
public bool _hovered = false, _track = false, _warp = false;
public int _damage = 1, _health = 2, _stamina, _staminaRemaining, _visibilityRange = 4, _hitRange, _priority = 1;
public Vector2I _address = -Vector2I.One, _range = Vector2I.Up;
public List<Vector2I> _path = new();
public float _movement = 0;
public EnemyController _enemyController;
public override void _Ready()
{
base._Ready();
}
public override void _Process(double delta)
{
base._Process(delta);
if (_hovered)
{
if (Input.IsActionJustPressed("leftClick"))
{
EmitSignal(SignalName.Clicked, this);
}
if (Input.IsActionJustPressed("rightClick"))
{
EmitSignal(SignalName.RightClicked, this);
}
}
}
public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);
}
public void Attack(PlayerController PLAYER)
{
PLAYER.ChangeHealth(-1, this);
}
public bool CanAttack()
{
return _address.Y <= _hitRange;
}
public void CounterAttack(Commander COMMANDER)
{
}
public virtual List<Vector2I> GetGoals(Map MAP)
{
List<Vector2I> firstOpenRow = [.. MAP._cells.Where(c => c.Y == MAP.GetFirstOpenRow() && !MAP._astar.IsPointSolid(c))];
return firstOpenRow;
}
public virtual List<Vector2I> GetBestPath(Map MAP)
{
List<Vector2I> goals = GetGoals(MAP);
List<List<Vector2I>> paths = new();
for (int i = 0; i < goals.Count; i++)
{
paths.Add(MAP.GetPath(_address, goals[i]));
}
List<Vector2I> bestPath = paths.OrderBy(p => p.Count).ThenBy(p => p.Last().X % 2).ToList()[0];
return bestPath;
}
public void GetRemainingStamina(Map MAP)
{
_staminaRemaining = _address.Y <= MAP.GetFirstOpenRow() ? 0 : _stamina;
}
public void RemainInPlace()
{
if (_path.Count <= 0)
{
_path.Add(_address);
}
else
{
_path.Add(_path.LastOrDefault());
}
}
public void TakeDamage(int DAMAGE, Commander ATTACKER)
{
_health -= DAMAGE;
CounterAttack(ATTACKER);
if (_health <= 0)
{
EmitSignal(SignalName.Death, this);
}
}
public void OnMouseEntered(){
_hovered = true;
}
public void OnMouseExited(){
_hovered = false;
}
}
-220
View File
@@ -1,220 +0,0 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
public partial class EnemyController : TurnController
{
public PackedScene _enemyScene = GD.Load<PackedScene>("res://Enemy.tscn");
public List<Enemy> _enemies = new();
public PlayerController _playerController;
<<<<<<< HEAD
public Tween _movementTween;
=======
public Dictionary<float, List<Tween>> _tweenStages = new();
public Tween _tween;
>>>>>>> f022333c9b378e5a77d8d2727f2a9cb16dd1b8f8
public void AddEnemies(int ENEMY_COUNT = 1)
{
for (int i = 0; i < ENEMY_COUNT; i++)
{
Enemy newEnemy = _enemyScene.Instantiate<Enemy>();
newEnemy.Death += RemoveEnemy;
newEnemy.Clicked += HandleEnemyClick;
newEnemy.RightClicked += HandleEnemyRightClick;
newEnemy._stamina = Globals._rng.Next(2,4+1);
newEnemy.Modulate = new Color(newEnemy._stamina == 2 ? "#FF0000" : newEnemy._stamina == 3 ? "#00FF00" : "#0000FF");
newEnemy._enemyController = this;
List<Vector2I> unoccupied = [.. _playArea._map._bottomRow.Where(c => _enemies.All(e => e._address != c))];
Vector2I randomCell = unoccupied[Globals._rng.Next(unoccupied.Count)];
SetEnemy(newEnemy, randomCell);
_enemies.Add(newEnemy);
AddChild(newEnemy);
}
}
public void AddEnemies(List<Vector2I> POSITIONS)
{
for (int i = 0; i < POSITIONS.Count; i++)
{
Enemy newEnemy = _enemyScene.Instantiate<Enemy>();
newEnemy.Death += RemoveEnemy;
newEnemy.Clicked += HandleEnemyClick;
newEnemy.RightClicked += HandleEnemyRightClick;
newEnemy._stamina = Globals._rng.Next(2,4+1);
newEnemy._hitRange = Globals._rng.Next(1,2+1);
newEnemy.Modulate = new Color(newEnemy._stamina == 2 ? "#FF0000" : newEnemy._stamina == 3 ? "#00FF00" : "#0000FF");
newEnemy._enemyController = this;
SetEnemy(newEnemy, POSITIONS[i]);
_enemies.Add(newEnemy);
AddChild(newEnemy);
}
}
public async Task BuildAnimationTween()
{
_tweenStages.Clear();
for (int i= 0; i < _enemies.Count; i++)
{
Enemy enemy = _enemies[i];
await enemy.AnimateMovement(this);
}
_tweenStages.OrderBy(s => s.Key);
}
public async Task BuildEnemyPaths()
{
Map map = _playArea._map;
_enemies.ForEach(e => e._path.Clear());
while (_enemies.Any(e => e._staminaRemaining > 0) && _enemies.Any(e => e._address.Y > map.GetFirstOpenRow()))
{
for (int i = 0; i < _enemies.Count; i++)
{
Enemy enemy = _enemies[i];
if (enemy._staminaRemaining <= 0 || enemy._address.Y <= map.GetFirstOpenRow())
{
enemy._path.Add(enemy._path.LastOrDefault(enemy._address));
continue;
}
List<Vector2I> path = enemy.GetBestPath(map);
if (path.Count == 0)
{
enemy._path.Add(enemy._path.LastOrDefault(enemy._address));
continue;
}
Vector2I cell = path[0];
GD.Print(cell);
map.SetCellEnemy(cell, enemy);
enemy._path.Add(cell);
enemy._staminaRemaining--;
}
}
}
public void EnemyAttacks()
{
List<Enemy> attackingEnemies = [.. _enemies.Where(e => e.CanAttack())];
for (int i = 0; i < attackingEnemies.Count; i++)
{
Enemy enemy = attackingEnemies[i];
enemy.Attack(_playerController);
enemy._staminaRemaining = Math.Max(enemy._staminaRemaining - 2, 0);
}
}
public void HandleEnemyClick(Enemy ENEMY)
{
if (ENEMY._staminaRemaining <= 0){
return;
}
TileMapLayer pathLayer = _playArea.GetNode<TileMapLayer>("PathLayer");
List<Vector2I> newPath = ENEMY.GetBestPath(_playArea._map);
pathLayer.GetUsedCells().ToList().ForEach(c => pathLayer.SetCell(c,0,Vector2I.Down*4));
for (int i = 0; i < newPath.Count; i++)
{
pathLayer.SetCell(newPath[i],0,Vector2I.One);
}
}
public void HandleEnemyRightClick(Enemy ENEMY)
{
RemoveEnemy(ENEMY);
}
public void Initiate()
{
List<Vector2I> positions = [.. _playArea.GetNode<TileMapLayer>("InitialPositions").GetUsedCells()];
AddEnemies(positions);
}
public void ProcessTweenStep(int STEP = 0)
{
if (_tweenStages.Count <= 0)
{
return;
}
if (STEP >= _tweenStages.Count)
{
EndTurn();
return;
}
if (_tween != null)
{
_tween.Kill();
}
_tween = CreateTween();
_tween.TweenInterval(0.5f);
float stage = _tweenStages.Keys.ElementAt(STEP);
List<Tween> stageTweens = _tweenStages[stage];
for (int i = 0; i < stageTweens.Count; i++)
{
Tween step = stageTweens[i];
_tween.Parallel().TweenSubtween(step);
}
_tween.TweenCallback(Callable.From(() => ProcessTweenStep(STEP + 1)));
}
public void RemoveEnemy(Enemy ENEMY_TO_REMOVE)
{
_enemies.Remove(ENEMY_TO_REMOVE);
_playArea._map.SetCellEnemy(ENEMY_TO_REMOVE._address, null);
ENEMY_TO_REMOVE.QueueFree();
}
public void SortEnemies()
{
_enemies = [.. _enemies.OrderByDescending(e => e._priority).ThenBy(e => e._address.Y).ThenBy(e => e._path.Count).ThenBy(e => Math.Abs(e._address.X - _playArea._map._maxX / 2))];
}
public override async Task StartTurn()
{
AddEnemies(1);
for (int i = 0; i < _enemies.Count; i++)
{
_enemies[i].StartTurn();
}
SortEnemies();
EnemyAttacks();
await BuildEnemyPaths();
await BuildAnimationTween();
ProcessTweenStep();
}
public void SetEnemy(Enemy ENEMY, Vector2I CELL)
{
if (CELL == new Vector2I(16, 14))
{
ENEMY._track = true;
}
_playArea._map.SetCellEnemy(CELL, ENEMY);
ENEMY.GlobalPosition = _playArea._map.GetCellPositionFromAddress(CELL);
}
}
+8 -1
View File
@@ -1,9 +1,16 @@
using Godot;
using System;
using System.Collections.Generic;
public partial class Globals : Node
public partial class Globals : Node2D
{
public static Random _rng = new();
public static float _gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity"), _drag = (float)ProjectSettings.GetSetting("physics/2d/default_linear_damp");
public static MouseHandler _mouse;
public static T GetRandomFromList<T>(List<T> TYPED_LIST)
{
return TYPED_LIST[_rng.Next(0,TYPED_LIST.Count)];
}
}
+52
View File
@@ -0,0 +1,52 @@
using Godot;
using System;
public partial class HoverableNode : Node2D
{
[Signal]
public delegate void HoverEventHandler(HoverableNode THIS, bool IS_HOVERED);
[Signal]
public delegate void ClickEventHandler(HoverableNode THIS, int CLICK_TYPE);
public bool _hovered;
public Area2D _bounds;
public override void _Ready()
{
base._Ready();
_bounds = GetNode<Area2D>("HoverBounds");
_bounds.MouseEntered += OnMouseEntered;
_bounds.MouseExited += OnMouseExited;
}
public override void _Process(double delta)
{
base._Process(delta);
if (_hovered)
{
if (Input.IsActionJustPressed("leftClick"))
{
EmitSignal(SignalName.Click, this, 0);
}
if (Input.IsActionJustPressed("rightClick"))
{
EmitSignal(SignalName.Click, this, 2);
}
if (Input.IsActionJustPressed("middleClick"))
{
EmitSignal(SignalName.Click, this, 1);
}
}
}
public virtual void OnMouseEntered()
{
_hovered = true;
EmitSignal(SignalName.Hover, this,_hovered);
}
public virtual void OnMouseExited()
{
_hovered = false;
EmitSignal(SignalName.Hover, this, _hovered);
}
}
+1
View File
@@ -0,0 +1 @@
uid://dqvysa2n208d3
+14 -20
View File
@@ -7,27 +7,30 @@ public partial class Main : Node
{
public PlayArea _playArea;
public PlayerController _playerController;
public EnemyController _enemyController;
public PegController _pegController;
public TurnController _turnController;
public Random _rng = new();
public override void _Ready()
{
base._Ready();
Globals._mouse = GetNode<MouseHandler>("MouseHandler");
_playArea = GetNode<PlayArea>("PlayArea");
_playerController = GetNode<PlayerController>("PlayerController");
_enemyController = GetNode<EnemyController>("EnemyController");
_pegController = GetNode<PegController>("PegController");
_playerController._enemyController = _enemyController;
_enemyController._playerController = _playerController;
_playerController._pegController = _pegController;
_pegController._playerController = _playerController;
_playerController._playArea = _playArea;
_enemyController._playArea = _playArea;
_pegController._playArea = _playArea;
_playerController._map = _playArea._map;
_pegController._map = _playArea._map;
_playerController.TurnDone += ChangeTurn;
_playerController.Death += EndGame;
_enemyController.TurnDone += ChangeTurn;
_pegController.TurnDone += ChangeTurn;
_enemyController.Initiate();
_pegController.Initiate();
_playerController.SetUpTowers();
ChangeTurn();
}
@@ -43,24 +46,15 @@ public partial class Main : Node
{
if(_turnController == _playerController)
{
ChangeTurn();
_playerController.EndTurn();
}
}
}
public async void ChangeTurn()
public void ChangeTurn()
{
if (_turnController != _playerController)
{
_turnController = _playerController;
await _playerController.StartTurn();
}
else
{
_turnController = _enemyController;
await _enemyController.StartTurn();
}
_turnController = _turnController == _playerController ? _pegController : _playerController;
_turnController.StartTurn();
}
public void EndGame(PlayerController PLAYER)
+110 -49
View File
@@ -3,31 +3,97 @@ using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
public partial class Map : TileMapLayer
{
public PackedScene _mapCellScene = GD.Load<PackedScene>("res://map_cell.tscn");
public int _minX, _maxX, _minY, _maxY, _mainSource = 0;
public string _isSolidString = "is_solid";
public string _isSolidString = "is_solid", _dispositionString = "disposition";
public Vector2 _cellSize, _sizeInPixels, _sizeInCells;
public Vector2I _pathTakenAtlasCoordinates = new Vector2I(4, 0);
public List<Vector2I> _cells = new(), _leftmostColumn = new(), _rightmostColumn = new(), _topRow = new(), _bottomRow = new();
public AStarGrid2D _astar = new();
public Dictionary<Vector2I, Enemy> _addressOccupants = new();
public Dictionary<Vector2I, MapCell> _cells = new(), _leftmostColumn = new(), _rightmostColumn = new(), _topRow = new(), _bottomRow = new();
public int _firstOpenRow
{
get
{
for (int i = 0; i < _maxY; i++)
{
if (!IsRowFull(i))
{
return i;
}
}
return -1;
}
}
public int _lastOpenRow
{
get
{
for (int i = _maxY; i > _minY; i--)
{
if (!IsRowFull(i))
{
return i;
}
}
return -1;
}
}
public int _firstOpenColumn
{
get
{
for (int i = 0; i < _maxX; i++)
{
if (!IsColumnnFull(i))
{
return i;
}
}
return -1;
}
}
public int _lastOpenColumn
{
get
{
for (int i = _maxX; i > _minX; i--)
{
if (!IsColumnnFull(i))
{
return i;
}
}
return -1;
}
}
public override void _Ready()
{
base._Ready();
// GD.Print(GlobalPosition);
List<Vector2I> usedCells = [.. GetUsedCells()];
_cellSize = TileSet.TileSize;
_cells = [.. GetUsedCells()];
_cells.ForEach(c => _addressOccupants[c] = null);
_minX = _cells.Min(c => c.X);
_maxX = _cells.Max(c => c.X);
_minY = _cells.Min(c => c.Y);
_maxY = _cells.Max(c => c.Y);
_leftmostColumn = [.. _cells.Where(c => c.X == _minX)];
_rightmostColumn = [.. _cells.Where(c => c.X == _maxX)];
_topRow = [.. _cells.Where(c => c.Y == _minY)];
_bottomRow = [.. _cells.Where(c => c.Y == _maxY)];
for (int i = 0; i < usedCells.Count; i++)
{
MapCell newMapCell = _mapCellScene.Instantiate<MapCell>();
Vector2I usedCell = usedCells[i];
newMapCell._address = usedCell;
newMapCell.GlobalPosition = newMapCell._address * _cellSize + _cellSize / 2;
// GD.Print(GlobalPosition, newMapCell.GlobalPosition);
newMapCell._occupant = null;
_cells[usedCell] = newMapCell;
AddChild(newMapCell);
}
_minX = _cells.Min(c => c.Value._address.X);
_maxX = _cells.Max(c => c.Value._address.X);
_minY = _cells.Min(c => c.Value._address.Y);
_maxY = _cells.Max(c => c.Value._address.Y);
_leftmostColumn = _cells.Where(c => c.Value._address.X == _minX).ToDictionary();
_rightmostColumn = _cells.Where(c => c.Value._address.X == _maxX).ToDictionary();
_topRow = _cells.Where(c => c.Value._address.Y == _minY).ToDictionary();
_bottomRow = _cells.Where(c => c.Value._address.Y == _maxY).ToDictionary();
_sizeInCells = new Vector2(_topRow.Count, _leftmostColumn.Count);
_sizeInPixels = _sizeInCells * _cellSize;
@@ -46,26 +112,15 @@ public partial class Map : TileMapLayer
}
return new Vector2I((int)Math.Floor(POSITION.X / _cellSize.X), (int)Math.Floor(POSITION.Y / _cellSize.Y));
}
public Vector2 GetCellPositionFromAddress(Vector2I CELL_ADDRESS)
public int GetCellDisposition(Vector2I ADDRESS)
{
return GlobalPosition + CELL_ADDRESS * _cellSize + _cellSize / 2;
return (int)GetCellTileData(ADDRESS).GetCustomData(_dispositionString);
}
public int GetFirstOpenRow()
public MapCellOccupant GetOccupant(Vector2I CELL_TO_CHECK)
{
for (int i = 0; i < _maxY; i++)
{
if (!IsRowFull(i))
{
return i;
}
}
return 1;
}
public Enemy GetOccupant(Vector2I CELL_TO_CHECK)
{
return _addressOccupants[CELL_TO_CHECK];
return _cells[CELL_TO_CHECK]._occupant;
}
public bool HasOccupant(Vector2I CELL_TO_CHECK)
@@ -82,33 +137,39 @@ public partial class Map : TileMapLayer
return hasOccupant || isSolid;
}
public bool IsColumnnFull(int COLUMN_TO_CHECK)
{
List<Vector2I> rowCells = [.. _cells.Where(c => c.Value._address.X == COLUMN_TO_CHECK).ToDictionary().Keys];
return rowCells.All(_astar.IsPointSolid);
}
public bool IsRowFull(int ROW_TO_CHECK)
{
List<Vector2I> rowCells = [.. _cells.Where(c => c.Y == ROW_TO_CHECK)];
List<Vector2I> rowCells = [.. _cells.Where(c => c.Value._address.Y == ROW_TO_CHECK).ToDictionary().Keys];
return rowCells.All(c => _astar.IsPointSolid(c));
return rowCells.All(_astar.IsPointSolid);
}
public void SetCellEnemy(Vector2I ADDRESS, Enemy ENEMY)
public void SetCellPeg(MapCell CELL, Peg PEG)
{
if (ENEMY != null)
if (PEG != null)
{
if (ENEMY._address != -Vector2I.One)
if (PEG._cell != null)
{
_addressOccupants[ENEMY._address] = null;
SetCellSolid(ENEMY._address);
PEG._cell._occupant = null;
SetCellSolid(_cells[PEG._address]);
}
ENEMY._address = ADDRESS;
PEG._cell = CELL;
PEG._address = CELL._address;
}
_addressOccupants[ADDRESS] = ENEMY;
SetCellSolid(ADDRESS);
CELL._occupant = PEG;
SetCellSolid(CELL);
}
public void SetCellSolid(Vector2I ADDRESS)
public void SetCellSolid(MapCell CELL)
{
_astar.SetPointSolid(ADDRESS, IsCellSolid(ADDRESS));
_astar.SetPointSolid(CELL._address, IsCellSolid(CELL._address));
// _astar.SetPointWeightScale(ADDRESS, IsCellSolid(ADDRESS) ? 1000 : 1);
}
@@ -121,16 +182,16 @@ public partial class Map : TileMapLayer
_astar.Update();
for (int i = 0; i < _cells.Count; i++)
{
_astar.SetPointWeightScale(_cells[i], _cells[i].Y * 2);
_astar.SetPointWeightScale(_cells.ElementAt(i).Value._address, Math.Abs(_cells.ElementAt(i).Value._address.Y * 2));
}
EvaluateSolidCells();
}
public List<Vector2I> GetPath(Vector2I FROM, Vector2I TO, bool INCLUDE_FROM = false)
public List<Vector2I> GetPath(Vector2I FROM, Vector2I TO, bool INCLUDE_FROM = false, bool PARTIAL = false)
{
_astar.SetPointSolid(FROM, false);
List<Vector2I> pathTaken = [.. _astar.GetIdPath(FROM, TO, true)];
List<Vector2I> pathTaken = [.. _astar.GetIdPath(FROM, TO, PARTIAL)];
_astar.SetPointSolid(FROM, true);
if (!INCLUDE_FROM)
@@ -144,7 +205,7 @@ public partial class Map : TileMapLayer
{
for (int i = 0; i < _cells.Count; i++)
{
SetCellSolid(_cells[i]);
SetCellSolid(_cells.ElementAt(i).Value);
}
}
+5 -1
View File
@@ -1,4 +1,4 @@
[gd_scene format=3 uid="uid://mjinvqj25wha"]
[gd_scene format=3 uid="uid://dqknim3lldrmv"]
[ext_resource type="Texture2D" uid="uid://cf554xlykq1o4" path="res://Art/tile_set.png" id="1_gfjgm"]
[ext_resource type="Script" uid="uid://d2ri1sa0jwtqm" path="res://Map.cs" id="2_3vi7k"]
@@ -11,7 +11,9 @@ texture = ExtResource("1_gfjgm")
texture_region_size = Vector2i(40, 40)
0:0/0 = 0
1:0/0 = 0
1:0/0/custom_data_1 = -1
2:0/0 = 0
2:0/0/custom_data_1 = 1
3:0/0 = 0
3:0/0/custom_data_0 = true
4:0/0 = 0
@@ -26,6 +28,8 @@ texture_region_size = Vector2i(40, 40)
tile_size = Vector2i(40, 40)
custom_data_layer_0/name = "is_solid"
custom_data_layer_0/type = 1
custom_data_layer_1/name = "disposition"
custom_data_layer_1/type = 2
sources/1 = SubResource("TileSetAtlasSource_trj13")
pattern_0 = SubResource("TileMapPattern_fjt81")
+15
View File
@@ -0,0 +1,15 @@
using Godot;
using System;
public partial class MapCell : Node2D
{
public Vector2I _address;
public MapCellOccupant _occupant;
public override void _Ready()
{
base._Ready();
}
}
+1
View File
@@ -0,0 +1 @@
uid://b8fx1wwyj30bg
+16
View File
@@ -0,0 +1,16 @@
using Godot;
using System;
public partial class MapCellOccupant : HoverableNode
{
public Vector2I _address;
public MapCell _cell;
public Disposition _disposition = Disposition.NONE;
public enum Disposition
{
NONE = -99,
FRIENDLY = 1,
NEUTRAL = 0,
HOSTILE = -1
}
}
+1
View File
@@ -0,0 +1 @@
uid://b3dlktsgeteuw
+18
View File
@@ -0,0 +1,18 @@
using Godot;
using System;
public partial class MouseHandler : Node
{
public enum ClickType
{
LEFT_CLICK,
MIDDLE_CLICK,
RIGHT_CLICK,
LEFT_HOLD,
MIDDLE_HOLD,
RIGHT_HOLD,
LEFT_DOUBLE,
MIDDLE_DOUBLE,
RIGHT_DOUBLE
}
}
+1
View File
@@ -0,0 +1 @@
uid://dewxuppyw2gtp
+91
View File
@@ -0,0 +1,91 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
public partial class Peg : MapCellOccupant
{
[Signal]
public delegate void DeathEventHandler(Peg THIS);
public int _id, _health = 2, _healthMax = 2, _stamina, _staminaRemaining, _movement = 0, _visibility;
public List<MapCell> _path = new();
public PegController _pegController;
public Map _map;
public List<PegAction> _actions;
public int _distanceToGoal
{
get
{
return GetBestPath().Count;
}
}
public override void _Ready()
{
base._Ready();
_actions = [.. GetNode<Node2D>("Actions").GetChildren().Cast<PegAction>()];
_map = _pegController._playArea._map;
}
public virtual PegAction SelectAction()
{
return _actions.FirstOrDefault(a => a.MeetsCriteria(this), null);
}
public virtual void CounterAct(Commander COMMANDER)
{
}
public virtual List<MapCell> GetBestPath(bool PARTIAL = false)
{
MapCell goal = Goal();
return [.. _map.GetPath(_address, goal._address, false, PARTIAL).Select(a => _map._cells[a])];
}
public virtual Dictionary<Vector2I, MapCell> GetEnemies()
{
return _map._cells.Where(c => (int)(c.Value._occupant?._disposition ?? Disposition.NONE) == -(int)_disposition).ToDictionary();
}
public virtual Dictionary<Vector2I, MapCell> GetVisibleCells()
{
Map map = _pegController._playArea._map;
return map._cells.Where(c => (c.Value._address - _address).Length() <= _visibility).ToDictionary();
}
public virtual Dictionary<Vector2I, MapCell> GetVisibleEnemies()
{
Dictionary<Vector2I, MapCell> visible = GetVisibleCells();
Dictionary<Vector2I, MapCell> enemies = GetEnemies();
return enemies.Keys.Intersect(visible.Keys).ToDictionary(e => e, e => enemies[e]);
}
public virtual MapCell Goal()
{
Dictionary<Vector2I, MapCell> enemyTerritory = _map._cells.Where(c => _map.GetCellDisposition(c.Value._address) == (_disposition == Disposition.FRIENDLY ? -1 : 1)).ToDictionary();
Dictionary<Vector2I, MapCell> closest = enemyTerritory.OrderByDescending(c => c.Value._address.Y).ThenBy(c => Math.Abs(c.Value._address.X - _address.X)).ToDictionary();
return closest.ElementAt(0).Value;
}
public virtual void StartTurn()
{
_staminaRemaining = _stamina;
_actions.ForEach(a => a.Reset());
}
public virtual void ChangeHealth(int DELTA)
{
_health += DELTA;
if (_health <= 0)
{
EmitSignal(SignalName.Death, this);
}
else if (_health > _healthMax)
{
_health = _healthMax;
}
}
}
+1
View File
@@ -0,0 +1 @@
uid://g2ucwg3k342p
+267
View File
@@ -0,0 +1,267 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
public partial class PegController : TurnController
{
public int _pegsCreated = 0, _pegsDestroyed = 0;
public List<PackedScene> _hostilePegScenes, _friendlyPegScenes, _neutralPegScenes;
public List<Peg> _pegs = new();
public PlayerController _playerController;
public Dictionary<string, List<Tuple<Peg, PegAction>>> _tweenStages = new();
public Tween _tween;
public XmlDocument _pegProbabilities = new();
public override void _Ready()
{
base._Ready();
_hostilePegScenes = [.. Directory.GetFiles("Pegs/HostilePegs/", "*.tscn").Select(f => GD.Load<PackedScene>(f))];
_friendlyPegScenes = [.. Directory.GetFiles("Pegs/FriendlyPegs/", "*.tscn").Select(f => GD.Load<PackedScene>(f))];
// _neutralPegScenes = [.. Directory.GetFiles("Pegs/NeutralPegs/", "*.tscn").Select(f => GD.Load<PackedScene>(f))];
// _pegProbabilities.Load("res://PegProbabilities.xml");
}
public void AddFriendlyPegs(int PEG_COUNT = 1)
{
for (int i = 0; i < PEG_COUNT; i++)
{
FriendlyPeg newFriendlyPeg = Globals.GetRandomFromList(_friendlyPegScenes).Instantiate<FriendlyPeg>();
newFriendlyPeg._id = _pegsCreated;
newFriendlyPeg.Death += HandlePegRemoval;
newFriendlyPeg.Click += HandlePegClick;
newFriendlyPeg._pegController = this;
Dictionary<Vector2I, MapCell> unoccupied = _playArea._map._bottomRow.Where(c => c.Value._occupant == null).ToDictionary();
MapCell randomCell = unoccupied.ElementAt(Globals._rng.Next(unoccupied.Keys.Count)).Value;
SetPeg(newFriendlyPeg, randomCell);
_pegs.Add(newFriendlyPeg);
AddChild(newFriendlyPeg);
_pegsCreated++;
}
}
public void AddFriendlyPegs(List<Vector2I> POSITIONS)
{
for (int i = 0; i < POSITIONS.Count; i++)
{
FriendlyPeg newFriendlyPeg = Globals.GetRandomFromList(_friendlyPegScenes).Instantiate<FriendlyPeg>();
newFriendlyPeg._id = _pegsCreated;
newFriendlyPeg.Scale *= _pegsCreated == 4 ? 1.5f : 1f;
newFriendlyPeg.Death += HandlePegRemoval;
newFriendlyPeg.Click += HandlePegClick;
newFriendlyPeg._pegController = this;
SetPeg(newFriendlyPeg, _map._cells[POSITIONS[i]]);
_pegs.Add(newFriendlyPeg);
AddChild(newFriendlyPeg);
_pegsCreated++;
}
}
public void AddHostilePegs(int PEG_COUNT = 1)
{
for (int i = 0; i < PEG_COUNT; i++)
{
HostilePeg newHostilePeg = Globals.GetRandomFromList(_hostilePegScenes).Instantiate<HostilePeg>();
newHostilePeg._id = _pegsCreated;
newHostilePeg.Death += HandlePegRemoval;
newHostilePeg.Click += HandlePegClick;
newHostilePeg._pegController = this;
Dictionary<Vector2I, MapCell> unoccupied = _map._bottomRow.Where(c => c.Value._occupant == null).ToDictionary();
MapCell randomCell = unoccupied.ElementAt(Globals._rng.Next(unoccupied.Count)).Value;
SetPeg(newHostilePeg, randomCell);
_pegs.Add(newHostilePeg);
AddChild(newHostilePeg);
_pegsCreated++;
}
}
public void AddHostilePegs(List<Vector2I> POSITIONS)
{
for (int i = 0; i < POSITIONS.Count; i++)
{
HostilePeg newHostilePeg = Globals.GetRandomFromList(_hostilePegScenes).Instantiate<HostilePeg>();
newHostilePeg._id = _pegsCreated;
newHostilePeg.Scale *= _pegsCreated == 4 ? 1.5f : 1f;
newHostilePeg.Death += HandlePegRemoval;
newHostilePeg.Click += HandlePegClick;
newHostilePeg._pegController = this;
newHostilePeg._map = _playArea._map;
SetPeg(newHostilePeg, _map._cells[POSITIONS[i]]);
_pegs.Add(newHostilePeg);
AddChild(newHostilePeg);
_pegsCreated++;
}
}
public void HandlePegTurn()
{
_tweenStages.Clear();
int loop = 0;
bool anyPegsActed = true;
while (anyPegsActed)
{
anyPegsActed = false;
for (int i = 0; i < _pegs.Count; i++)
{
Peg peg = _pegs[i];
PegAction action = peg.SelectAction();
if (action != null)
{
action.DoImmediately(peg);
string key = action._priority + ":" + loop;
if (!_tweenStages.ContainsKey(key))
{
_tweenStages[key] = new();
}
_tweenStages[key].Add(new(peg, action));
if (!anyPegsActed)
{
anyPegsActed = true;
}
peg._staminaRemaining -= action._cost;
}
}
loop++;
}
ProcessTween();
}
public void HandlePegClick(Node CLICKED_NODE, int CLICK_TYPE)
{
if (CLICKED_NODE is not Peg peg)
{
return;
}
if (CLICK_TYPE == 0)
{
Map map = _playArea._map;
TileMapLayer pathLayer = _playArea.GetNode<TileMapLayer>("PathLayer");
List<Vector2I> pl = [.. pathLayer.GetUsedCells()];
Dictionary<Vector2I, MapCell> visible = peg.GetVisibleCells();
for (int i = 0; i < pl.Count; i++)
{
Vector2I cell = pl[i];
pathLayer.GetUsedCells().ToList().ForEach(c => pathLayer.SetCell(cell,0,Vector2I.Down + Vector2I.Right*(visible.ContainsKey(cell) ? 1 : 4)));
}
}
else if (CLICK_TYPE == 1)
{
TileMapLayer pathLayer = _playArea.GetNode<TileMapLayer>("PathLayer");
List<MapCell> newPath = peg.GetBestPath(true);
pathLayer.GetUsedCells().ToList().ForEach(c => pathLayer.SetCell(c,0,Vector2I.Down + Vector2I.Right*4));
for (int i = 0; i < newPath.Count; i++)
{
pathLayer.SetCell(newPath[i]._address,0,Vector2I.One);
}
}
else if (CLICK_TYPE == 2)
{
HandlePegRemoval(peg);
}
}
public void HandlePegRemoval(Peg PEG_TO_REMOVE)
{
_pegs.Remove(PEG_TO_REMOVE);
_playArea._map.SetCellPeg(_map._cells[PEG_TO_REMOVE._address], null);
PEG_TO_REMOVE.QueueFree();
_pegsDestroyed++;
}
public void HandlePegSort()
{
_pegs = [.. _pegs.OrderBy(p => p._address.Y).ThenBy(p => p._distanceToGoal).ThenBy(p => Math.Abs(p._address.X - _playArea._map._maxX / 2))];
}
public void Initiate()
{
TileMapLayer init = _playArea.GetNode<TileMapLayer>("InitialPositions");
List<Vector2I> initPos = [.. init.GetUsedCells()];
List<Vector2I> positions = [.. initPos.OrderBy(c => c.Y).ThenBy(c => c.X)];
List<Vector2I> hPositions = [.. positions.Where(c => (int)init.GetCellTileData(c).GetCustomData("disposition") == -1)];
List<Vector2I> fPositions = [.. positions.Where(c => (int)init.GetCellTileData(c).GetCustomData("disposition") == 1)];
AddHostilePegs(hPositions);
AddFriendlyPegs(fPositions);
_playArea.HighlightCells();
}
public void ProcessTween()
{
_tweenStages = _tweenStages.OrderBy(s => int.Parse(s.Key.Split(":")[0])).ThenBy(s => int.Parse(s.Key.Split(":")[1])).ToDictionary();
if (_tweenStages.Count <= 0)
{
EndTurn();
return;
}
_tween?.Kill();
_tween = CreateTween();
for (int i = 0; i < _tweenStages.Count; i++)
{
_tween.Chain().TweenInterval(0.5f);
List<Tuple<Peg, PegAction>> tweenSteps = _tweenStages.Values.ElementAt(i);
for (int j = 0; j < tweenSteps.Count; j++)
{
Tuple<Peg, PegAction> step = tweenSteps[j];
Peg peg = step.Item1;
PegAction action = step.Item2;
Tween tween = action.CreateAnimation(peg);
if (tween != null)
{
_tween.Parallel().TweenSubtween(tween);
}
}
}
_tween.TweenCallback(Callable.From(EndTurn));
}
public override void StartTurn()
{
AddHostilePegs(4);
for (int i = 0; i < _pegs.Count; i++)
{
_pegs[i].StartTurn();
}
HandlePegSort();
HandlePegTurn();
_playArea.HighlightCells();
}
public void SetPeg(Peg PEG, MapCell CELL)
{
_map.SetCellPeg(CELL, PEG);
PEG.GlobalPosition = CELL.GlobalPosition;
}
}
+3
View File
@@ -0,0 +1,3 @@
<xml>
</xml>
+58
View File
@@ -0,0 +1,58 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class BasicMovement : PegAction
{
public override void _Ready()
{
base._Ready();
_category = "movement";
_priority = 0;
_cost = 1;
_range = 2^32;
_usesMax = 2^32;
_usesRemaining = _usesMax;
}
public override Tween CreateAnimation(Peg PEG)
{
PegController pegController = PEG._pegController;
Map map = pegController._playArea._map;
MapCell cell = PEG._path[0];
Tween subtween = CreateTween();
Vector2 target = cell.GlobalPosition;
subtween.TweenProperty(PEG, "global_position", target, 0.25f);
PEG._path.RemoveAt(0);
return subtween;
}
public override void DoImmediately(Peg PEG)
{
List<MapCell> path = PEG.GetBestPath(true);
PegController pegController = PEG._pegController;
Map map = pegController._playArea._map;
if (path?.Count == 0)
{
return;
}
MapCell cell = path[0];
map.SetCellPeg(cell, PEG);
PEG._path.Add(cell);
}
public override bool MeetsCriteria(Peg PEG)
{
List<MapCell> bestPath = PEG.GetBestPath(true);
return base.MeetsCriteria(PEG)
&& bestPath.Count > 0
&& PEG._map.GetCellDisposition(bestPath[0]._address) != -(int)PEG._disposition;
}
}
+1
View File
@@ -0,0 +1 @@
uid://hp5iucbq5brg
+35
View File
@@ -0,0 +1,35 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class ShootShortbow : PegAction
{
public override void _Ready()
{
base._Ready();
_category = "attack";
_priority = 1;
_cost = 2;
_range = 2;
_usesMax = 1;
_usesRemaining = _usesMax;
}
public override Tween CreateAnimation(Peg PEG)
{
MapCell target = Target(PEG);
Tween subtween = CreateTween();
subtween.TweenProperty(_image, "visible", true, 0.0f);
subtween.TweenProperty(_image, "rotation", PEG.GetAngleTo(target.GlobalPosition), 0.0f);
subtween.TweenProperty(_image, "global_position", target.GlobalPosition, 0.5f);
subtween.TweenCallback(Callable.From(() =>
{
PEG._pegController._playerController.ChangeHealth(-2, this);
Position = Vector2.Zero;
Visible = false;
}));
return subtween;
}
}
+1
View File
@@ -0,0 +1 @@
uid://dt7qbvowj1sm4
+35
View File
@@ -0,0 +1,35 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class SwingShortsword : PegAction
{
public override void _Ready()
{
base._Ready();
_category = "attack";
_priority = 1;
_cost = 2;
_range = 1;
_usesMax = 1;
_usesRemaining = _usesMax;
}
public override Tween CreateAnimation(Peg PEG)
{
MapCell target = Target(PEG);
// GD.Print(target);
Tween subtween = CreateTween();
subtween.TweenProperty(_image, "visible", true, 0.0f);
subtween.TweenProperty(_image, "rotation", PEG.GetAngleTo(target.GlobalPosition), 0.0f);
subtween.TweenProperty(_image, "global_position", target.GlobalPosition, 0.5f);
subtween.TweenCallback(Callable.From(() =>
{
PEG._pegController._playerController.ChangeHealth(-2, this);
_image.Position = Vector2.Zero;
_image.Visible = false;
}));
return subtween;
}
}
+1
View File
@@ -0,0 +1 @@
uid://td6dv1t4y5os
+43
View File
@@ -0,0 +1,43 @@
using Godot;
using System;
public partial class ThrustSpear : PegAction
{
public override void _Ready()
{
base._Ready();
_category = "attack";
_priority = 1;
_cost = 1;
_range = 1;
_usesMax = 1;
_usesRemaining = _usesMax;
}
public override Tween CreateAnimation(Peg PEG)
{
MapCell target = Target(PEG);
if (target == PEG._cell)
{
return null;
}
Tween subtween = CreateTween();
subtween.TweenProperty(_image, "visible", true, 0.0f);
subtween.TweenProperty(_image, "rotation", PEG.GetAngleTo(target.GlobalPosition), 0.0f);
subtween.TweenProperty(_image, "global_position", target.GlobalPosition, 0.5f);
subtween.TweenCallback(Callable.From(() =>
{
((Peg)target?._occupant)?.ChangeHealth(-1);
_image.Position = Vector2.Zero;
_image.Visible = false;
}));
return subtween;
}
public override MapCell Target(Peg PEG)
{
return PEG.Goal();
}
}
+1
View File
@@ -0,0 +1 @@
uid://bj2lg1voxioq7
+9
View File
@@ -0,0 +1,9 @@
[gd_scene format=3 uid="uid://bup5oli00p3lg"]
[ext_resource type="Script" uid="uid://hp5iucbq5brg" path="res://Pegs/Actions/BasicMovement.cs" id="1_u1rld"]
[node name="BasicMovement" type="Node2D" unique_id=460007250]
script = ExtResource("1_u1rld")
[node name="Image" type="Sprite2D" parent="." unique_id=1133735272]
visible = false
+12
View File
@@ -0,0 +1,12 @@
[gd_scene format=3 uid="uid://duspilwelsiy3"]
[ext_resource type="Script" uid="uid://dt7qbvowj1sm4" path="res://Pegs/Actions/ShootShortbow.cs" id="1_yhiab"]
[ext_resource type="Texture2D" uid="uid://32m5teus1cjj" path="res://Art/tower.png" id="2_uaien"]
[node name="ShootShortbow" type="Node2D" unique_id=518048625]
script = ExtResource("1_yhiab")
[node name="Image" type="Sprite2D" parent="." unique_id=944294157]
visible = false
scale = Vector2(0.1, 0.1)
texture = ExtResource("2_uaien")
+12
View File
@@ -0,0 +1,12 @@
[gd_scene format=3 uid="uid://c6df6ib0qan5g"]
[ext_resource type="Script" uid="uid://td6dv1t4y5os" path="res://Pegs/Actions/SwingShortsword.cs" id="1_rflgk"]
[ext_resource type="Texture2D" uid="uid://32m5teus1cjj" path="res://Art/tower.png" id="2_fs74r"]
[node name="Shortsword" type="Node2D" unique_id=518048625]
script = ExtResource("1_rflgk")
[node name="Image" type="Sprite2D" parent="." unique_id=906537972]
visible = false
scale = Vector2(0.1, 0.1)
texture = ExtResource("2_fs74r")
+13
View File
@@ -0,0 +1,13 @@
[gd_scene format=3 uid="uid://xx4n81m8hbxv"]
[ext_resource type="Script" uid="uid://bj2lg1voxioq7" path="res://Pegs/Actions/ThrustSpear.cs" id="1_revbx"]
[ext_resource type="Texture2D" uid="uid://32m5teus1cjj" path="res://Art/tower.png" id="2_nwcvh"]
[node name="ThrustSpear" type="Node2D" unique_id=460007250]
script = ExtResource("1_revbx")
[node name="Image" type="Sprite2D" parent="." unique_id=1133735272]
visible = false
position = Vector2(0, -4.999999)
scale = Vector2(0.1, 0.1)
texture = ExtResource("2_nwcvh")
+13
View File
@@ -0,0 +1,13 @@
using Godot;
using System;
public partial class FriendlyPeg : Peg
{
public override void _Ready()
{
base._Ready();
_disposition = Disposition.FRIENDLY;
}
}
+1
View File
@@ -0,0 +1 @@
uid://fxx1mrrxxqip
+25
View File
@@ -0,0 +1,25 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class Spearman : FriendlyPeg
{
public override void _Ready()
{
base._Ready();
_stamina = 2;
_visibility = 4;
}
public override MapCell Goal()
{
Dictionary<Vector2I, MapCell> enemies = GetVisibleEnemies();
if (enemies.Count == 0)
{
return _cell;
}
Dictionary<Vector2I, MapCell> closest = enemies.OrderBy(e => (e.Value._occupant._address - _address).Length()).ToDictionary();
return closest.ElementAt(0).Value;
}
}
+1
View File
@@ -0,0 +1 @@
uid://dd4k8egcg3r2v
+43
View File
@@ -0,0 +1,43 @@
[gd_scene format=3 uid="uid://b5rrpaj7up7w3"]
[ext_resource type="Script" uid="uid://dd4k8egcg3r2v" path="res://Pegs/FriendlyPegs/Spearman.cs" id="1_rd6ui"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_v2nt8"]
[ext_resource type="PackedScene" uid="uid://xx4n81m8hbxv" path="res://Pegs/Actions/thrust_spear.tscn" id="3_ig48t"]
[ext_resource type="PackedScene" uid="uid://bup5oli00p3lg" path="res://Pegs/Actions/basic_movement.tscn" id="4_gi7y5"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[sub_resource type="CircleShape2D" id="CircleShape2D_6w6fg"]
radius = 12.5
[node name="Spearman" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_rd6ui")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
modulate = Color(1, 1, 0, 1)
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_v2nt8")
[node name="Actions" type="Node2D" parent="." unique_id=2023031702]
[node name="ThrustSpear" parent="Actions" unique_id=460007250 instance=ExtResource("3_ig48t")]
[node name="BasicMovement" parent="Actions" unique_id=791425339 instance=ExtResource("4_gi7y5")]
[node name="HoverBounds" type="Area2D" parent="." unique_id=937525982]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=2142666816]
shape = SubResource("CircleShape2D_6w6fg")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+17
View File
@@ -0,0 +1,17 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public partial class HostilePeg : Peg
{
public override void _Ready()
{
base._Ready();
_disposition = Disposition.HOSTILE;
}
}
+12
View File
@@ -0,0 +1,12 @@
using Godot;
using System;
public partial class Archer : HostilePeg
{
public override void _Ready()
{
base._Ready();
_stamina = 2;
_visibility = 4;
}
}
+1
View File
@@ -0,0 +1 @@
uid://b3a0x3r3yx861
+12
View File
@@ -0,0 +1,12 @@
using Godot;
using System;
public partial class Infantry : HostilePeg
{
public override void _Ready()
{
base._Ready();
_stamina = 3;
_visibility = 3;
}
}
+1
View File
@@ -0,0 +1 @@
uid://xlg4cblo1vf1
+43
View File
@@ -0,0 +1,43 @@
[gd_scene format=3 uid="uid://dwqhme11j5ihb"]
[ext_resource type="Script" uid="uid://b3a0x3r3yx861" path="res://Pegs/HostilePegs/Archer.cs" id="1_ij48w"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_j7but"]
[ext_resource type="PackedScene" uid="uid://duspilwelsiy3" path="res://Pegs/Actions/shoot_shortbow.tscn" id="3_c81uf"]
[ext_resource type="PackedScene" uid="uid://bup5oli00p3lg" path="res://Pegs/Actions/basic_movement.tscn" id="3_j7but"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[sub_resource type="CircleShape2D" id="CircleShape2D_6w6fg"]
radius = 12.5
[node name="Archer" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_ij48w")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
self_modulate = Color(0, 0, 1, 1)
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_j7but")
[node name="Actions" type="Node2D" parent="." unique_id=96111050]
[node name="ShootShortbow" parent="Actions" unique_id=518048625 instance=ExtResource("3_c81uf")]
[node name="BasicMovement" parent="Actions" unique_id=460007250 instance=ExtResource("3_j7but")]
[node name="HoverBounds" type="Area2D" parent="." unique_id=937525982]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=2142666816]
shape = SubResource("CircleShape2D_6w6fg")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+43
View File
@@ -0,0 +1,43 @@
[gd_scene format=3 uid="uid://d55ut168gh3k"]
[ext_resource type="Script" uid="uid://xlg4cblo1vf1" path="res://Pegs/HostilePegs/Infantry.cs" id="1_wlksp"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_b77ka"]
[ext_resource type="PackedScene" uid="uid://c6df6ib0qan5g" path="res://Pegs/Actions/swing_shortsword.tscn" id="3_b77ka"]
[ext_resource type="PackedScene" uid="uid://bup5oli00p3lg" path="res://Pegs/Actions/basic_movement.tscn" id="4_b77ka"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[sub_resource type="CircleShape2D" id="CircleShape2D_6w6fg"]
radius = 12.5
[node name="Infantry" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_wlksp")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
self_modulate = Color(1, 0, 0, 1)
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_b77ka")
[node name="Actions" type="Node2D" parent="." unique_id=1442443799]
[node name="Shortsword" parent="Actions" unique_id=518048625 instance=ExtResource("3_b77ka")]
[node name="BasicMovement" parent="Actions" unique_id=460007250 instance=ExtResource("4_b77ka")]
[node name="HoverBounds" type="Area2D" parent="." unique_id=937525982]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=2142666816]
shape = SubResource("CircleShape2D_6w6fg")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+14
View File
@@ -0,0 +1,14 @@
using Godot;
using System;
public partial class NeutralPeg : Peg
{
public override void _Ready()
{
base._Ready();
_disposition = Disposition.NEUTRAL;
}
}
+1
View File
@@ -0,0 +1 @@
uid://hcna8x41gtkq
+43
View File
@@ -0,0 +1,43 @@
using Godot;
using System;
public partial class PegAction : Node2D
{
public string _category;
public int _priority, _cost, _range, _usesMax, _usesRemaining, _triggers = 0;
public Sprite2D _image;
public override void _Ready()
{
base._Ready();
_image = GetNode<Sprite2D>("Image");
}
public virtual Tween CreateAnimation(Peg PEG)
{
return null;
}
public virtual void DoImmediately(Peg PEG)
{
}
public virtual bool MeetsCriteria(Peg PEG)
{
MapCell target = Target(PEG);
return PEG._staminaRemaining >= _cost
&& _usesRemaining > 0
&& (PEG._address - target._address).Length() <= _range;
}
public virtual void Reset()
{
_usesRemaining = _usesMax;
}
public virtual MapCell Target(Peg PEG)
{
return PEG.Goal();
}
}
+1
View File
@@ -0,0 +1 @@
uid://dpa15pxib2qyr
+36
View File
@@ -0,0 +1,36 @@
[gd_scene format=3 uid="uid://tym3gfecxnhf"]
[ext_resource type="Script" uid="uid://fxx1mrrxxqip" path="res://Pegs/FriendlyPeg.cs" id="1_d26yj"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="1_q81kk"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[sub_resource type="CircleShape2D" id="CircleShape2D_6w6fg"]
radius = 12.5
[node name="FriendlyPeg" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_d26yj")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("1_q81kk")
[node name="Actions" type="Node2D" parent="." unique_id=2023031702]
[node name="HoverBounds" type="Area2D" parent="." unique_id=937525982]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=2142666816]
shape = SubResource("CircleShape2D_6w6fg")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+17 -6
View File
@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://drt7w0eqp13tu"]
[gd_scene format=3 uid="uid://43ty0uit6ylb"]
[ext_resource type="Script" uid="uid://dfba4vq6jv0a6" path="res://Enemy.cs" id="1_4gyqm"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="1_7k104"]
[ext_resource type="Script" uid="uid://dfba4vq6jv0a6" path="res://Pegs/HostilePeg.cs" id="1_nc8fp"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_0icqg"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
@@ -9,17 +9,28 @@ bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[node name="Enemy" type="StaticBody2D" unique_id=1417697759]
[sub_resource type="CircleShape2D" id="CircleShape2D_6w6fg"]
radius = 12.5
[node name="HostilePeg" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_4gyqm")
script = ExtResource("1_nc8fp")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("1_7k104")
texture = ExtResource("2_0icqg")
[node name="Actions" type="Node2D" parent="." unique_id=2023031702]
[node name="HoverBounds" type="Area2D" parent="." unique_id=937525982]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=2142666816]
shape = SubResource("CircleShape2D_6w6fg")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+36
View File
@@ -0,0 +1,36 @@
[gd_scene format=3 uid="uid://d3jw2bvkr8ahq"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="1_bdrbe"]
[ext_resource type="Script" uid="uid://hcna8x41gtkq" path="res://Pegs/NeutralPeg.cs" id="1_vrgbl"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[sub_resource type="CircleShape2D" id="CircleShape2D_6w6fg"]
radius = 12.5
[node name="NeutralPeg" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_vrgbl")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("1_bdrbe")
[node name="Actions" type="Node2D" parent="." unique_id=2023031702]
[node name="HoverBounds" type="Area2D" parent="." unique_id=937525982]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=2142666816]
shape = SubResource("CircleShape2D_6w6fg")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+9
View File
@@ -0,0 +1,9 @@
[gd_scene format=3 uid="uid://bj2qrn0l01us1"]
[ext_resource type="Script" uid="uid://dpa15pxib2qyr" path="res://Pegs/PegAction.cs" id="1_8o8tf"]
[node name="PegAction" type="Node2D" unique_id=460007250]
script = ExtResource("1_8o8tf")
[node name="Image" type="Sprite2D" parent="." unique_id=1133735272]
visible = false
+8 -11
View File
@@ -8,12 +8,10 @@ public partial class PlayArea : Node2D
public Node2D _leftEdge, _rightEdge;
public Area2D _region;
public Map _map;
public Bucket _bucket;
public override void _Ready()
{
base._Ready();
_bucket = GetNode<Bucket>("Bucket");
_region = GetNode<Area2D>("Region");
_leftEdge = GetNode<Node2D>("LeftEdge");
@@ -23,33 +21,32 @@ public partial class PlayArea : Node2D
_map = GetNode<Map>("Map");
TileMapLayer occupiedSpaces = GetNode<TileMapLayer>("OccupiedSpaces");
occupiedSpaces.SetCell(Vector2I.Zero, 0, new Vector2I(4,0));
}
public override void _Process(double delta)
{
base._Process(delta);
_bucket.Move();
}
public void HighlightCells()
{
TileMapLayer occupiedSpaces = GetNode<TileMapLayer>("OccupiedSpaces");
_map._cells.ForEach(c =>
for (int i = 0; i < _map._cells.Count; i++)
{
if (_map.HasOccupant(c))
MapCell c = _map._cells.ElementAt(i).Value;
if (c._occupant != null)
{
occupiedSpaces.SetCell(c, 0, new Vector2I(4,0));
occupiedSpaces.SetCell(c._address, 0, new Vector2I(4,0));
}
else if (_map._astar.IsPointSolid(c))
else if (_map._astar.IsPointSolid(c._address))
{
occupiedSpaces.SetCell(c._address, 0, new Vector2I(3,1));
}
else
{
occupiedSpaces.SetCell(c, 0, Vector2I.Down*4);
occupiedSpaces.SetCell(c._address, 0, new Vector2I(4,1));
}
});
}
}
}
+12 -3
View File
@@ -9,17 +9,26 @@ public partial class PlayerController : TurnController
[Signal]
public delegate void DeathEventHandler(PlayerController THIS);
public bool _dead = false;
public int _health, _healthMax = 100;
public EnemyController _enemyController;
public int _health, _healthMax = 100, _gold = 0;
public PegController _pegController;
public PackedScene _commanderScene = GD.Load<PackedScene>("res://Commander.tscn");
public List<Tower> _towers = new();
public Bucket _bucket;
public override void _Ready()
{
_health = _healthMax;
base._Ready();
_bucket = GetNode<Bucket>("Bucket");
}
public override void _Process(double delta)
{
base._Process(delta);
_bucket.Move();
}
public void ChangeHealth(int DAMAGE, Node IMPETUS = null)
{
_health += DAMAGE;
@@ -63,7 +72,7 @@ public partial class PlayerController : TurnController
_towers[3].AddChild(newCommander);
}
public override async Task StartTurn()
public override void StartTurn()
{
_towers.ForEach(t => t.StartTurn());
}
+13 -19
View File
@@ -3,22 +3,22 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
public partial class Tower : Sprite2D
public partial class Tower : HoverableNode
{
public bool _hovered, _aiming;
public bool _aiming;
public int _launchSpeed = 1000, _arcIterations = 50;
public Vector2 _aimOffset, _arcEnd;
public List<Vector2> _arc = new();
public Marker2D _offset, _attackSpawn;
public Marker2D _offset, _ballSpawn;
public Area2D _area;
public Commander _commander;
public override void _Ready()
{
base._Ready();
_area = GetNode<Area2D>("Area");
_offset = GetNode<Marker2D>("Offset");
_attackSpawn = GetNode<Marker2D>("AttackSpawn");
_ballSpawn = GetNode<Marker2D>("BallSpawn");
// Click += HandleClick;
}
public override void _Process(double delta)
{
@@ -29,19 +29,19 @@ public partial class Tower : Sprite2D
{
if (_arcEnd != GetGlobalMousePosition())
{
DrawArc(_attackSpawn.GlobalPosition, GetGlobalMousePosition());
DrawArc(_ballSpawn.GlobalPosition, GetGlobalMousePosition());
}
if (Input.IsActionJustPressed("rightClick"))
{
_commander.UnloadAttack();
_commander.UnloadBall();
_aiming = false;
}
else if (Input.IsActionJustPressed("leftClick"))
{
_aimOffset = ToLaunchVector(CalculateLaunchAngle(_attackSpawn.GlobalPosition, GetGlobalMousePosition()));
_aimOffset = ToLaunchVector(CalculateLaunchAngle(_ballSpawn.GlobalPosition, GetGlobalMousePosition()));
_commander.ShootCurrentAttack(_aimOffset);
_commander.ShootCurrentBall(_aimOffset);
ClearArc();
_aiming = false;
@@ -52,10 +52,11 @@ public partial class Tower : Sprite2D
if (Input.IsActionJustPressed("leftClick"))
{
_aiming = true;
_commander.LoadAttack(_attackSpawn.Position);
_commander.LoadBall(_ballSpawn.Position);
}
}
}
}
public float CalculateLaunchAngle(Vector2 START, Vector2 END, int MAX_ITERATIONS = 20)
@@ -111,7 +112,7 @@ public partial class Tower : Sprite2D
public void ClearArc()
{
Path2D path = _commander._attack.GetNode<Path2D>("PredictedPath");
Path2D path = _commander._ball.GetNode<Path2D>("PredictedPath");
path.Curve.ClearPoints();
}
@@ -143,7 +144,7 @@ public partial class Tower : Sprite2D
}
}
Path2D path = _commander._attack.GetNode<Path2D>("PredictedPath");
Path2D path = _commander._ball.GetNode<Path2D>("PredictedPath");
path.Curve.ClearPoints();
for (int i = 0; i < arc.Count; i++)
@@ -192,11 +193,4 @@ public partial class Tower : Sprite2D
return Vector2.FromAngle(ANGLE) * _launchSpeed;
}
public void OnMouseEntered(){
_hovered = true;
}
public void OnMouseExited(){
_hovered = true;
}
}
+2 -2
View File
@@ -7,8 +7,8 @@ public partial class TurnController : Node2D
[Signal]
public delegate void TurnDoneEventHandler();
public PlayArea _playArea;
public virtual async Task StartTurn()
public Map _map;
public virtual void StartTurn()
{
}
+7 -5
View File
@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://cevk7yax5tvej"]
[ext_resource type="Script" uid="uid://dm2gyxmgwbmg8" path="res://Attack.cs" id="1_63pi1"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_hqc8w"]
[ext_resource type="Script" uid="uid://dm2gyxmgwbmg8" path="res://Ball.cs" id="1_41u45"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_ktgx5"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_63pi1"]
bounce = 0.25
@@ -11,19 +11,21 @@ radius = 12.5
[sub_resource type="Curve2D" id="Curve2D_63pi1"]
[node name="Attack" type="RigidBody2D" unique_id=1225359241]
[node name="Ball" type="RigidBody2D" unique_id=1225359241]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_63pi1")
contact_monitor = true
max_contacts_reported = 100
script = ExtResource("1_63pi1")
script = ExtResource("1_41u45")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1448070524]
shape = SubResource("CircleShape2D_7yfhp")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1583277900]
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_hqc8w")
texture = ExtResource("2_ktgx5")
[node name="Ray" type="RayCast2D" parent="." unique_id=113171676]
[node name="PredictedPath" type="Path2D" parent="." unique_id=1505290715]
modulate = Color(1, 0, 1, 1)
-6
View File
@@ -1,6 +0,0 @@
[gd_scene format=3 uid="uid://c6b188d2a20eq"]
[ext_resource type="Script" uid="uid://brsi76xcgx3et" path="res://EnemyController.cs" id="1_tkpyo"]
[node name="EnemyController" type="Node2D" unique_id=197453707]
script = ExtResource("1_tkpyo")
+10
View File
@@ -0,0 +1,10 @@
[gd_scene format=3 uid="uid://dse0sugndsrs"]
[ext_resource type="Script" uid="uid://dqvysa2n208d3" path="res://HoverableNode.cs" id="1_14v3m"]
[node name="HoverableNode" type="Node2D" unique_id=946672764]
script = ExtResource("1_14v3m")
[node name="HoverBounds" type="Area2D" parent="." unique_id=783465962]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=585114419]
+5 -2
View File
@@ -2,8 +2,9 @@
[ext_resource type="Script" uid="uid://cg1m762ed04kv" path="res://Main.cs" id="1_ig7tw"]
[ext_resource type="PackedScene" uid="uid://dumcridek4xy3" path="res://play_area.tscn" id="2_1bvp3"]
[ext_resource type="PackedScene" uid="uid://c6b188d2a20eq" path="res://enemy_controller.tscn" id="4_1bvp3"]
[ext_resource type="PackedScene" uid="uid://bxlt2ap0dym1x" path="res://peg_controller.tscn" id="3_lquwl"]
[ext_resource type="PackedScene" uid="uid://b7kvx7p0b2086" path="res://player_controller.tscn" id="4_lquwl"]
[ext_resource type="PackedScene" path="res://mouse_handler.tscn" id="5_lquwl"]
[node name="Main" type="Node" unique_id=535208469]
script = ExtResource("1_ig7tw")
@@ -11,6 +12,8 @@ script = ExtResource("1_ig7tw")
[node name="PlayArea" parent="." unique_id=1123610167 instance=ExtResource("2_1bvp3")]
position = Vector2(360, 180)
[node name="EnemyController" parent="." unique_id=1894449838 instance=ExtResource("4_1bvp3")]
[node name="PegController" parent="." unique_id=197453707 instance=ExtResource("3_lquwl")]
[node name="PlayerController" parent="." unique_id=364781168 instance=ExtResource("4_lquwl")]
[node name="MouseHandler" parent="." unique_id=1823071759 instance=ExtResource("5_lquwl")]
+11
View File
@@ -0,0 +1,11 @@
[gd_scene format=3 uid="uid://cqwi2kesqh5wt"]
[ext_resource type="Script" uid="uid://b8fx1wwyj30bg" path="res://MapCell.cs" id="1_jkeij"]
[ext_resource type="Texture2D" uid="uid://c5jj7yhlnodxt" path="res://Art/star.png" id="2_ugbl7"]
[node name="MapCell" type="Node2D" unique_id=953237004]
script = ExtResource("1_jkeij")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=733491629]
scale = Vector2(0.025, 0.025)
texture = ExtResource("2_ugbl7")
+10
View File
@@ -0,0 +1,10 @@
[gd_scene format=3 uid="uid://d4nyjj5740ww5"]
[ext_resource type="Script" uid="uid://b3dlktsgeteuw" path="res://MapCellOccupant.cs" id="1_2wshj"]
[node name="MapCellOccupant" type="Node2D" unique_id=946672764]
script = ExtResource("1_2wshj")
[node name="HoverBounds" type="Area2D" parent="." unique_id=783465962]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=585114419]
+6
View File
@@ -0,0 +1,6 @@
[gd_scene format=3 uid="uid://by0a5f2ft0u03"]
[ext_resource type="Script" uid="uid://dewxuppyw2gtp" path="res://MouseHandler.cs" id="1_r4hv2"]
[node name="MouseHandler" type="Node2D" unique_id=215972463]
script = ExtResource("1_r4hv2")
+34
View File
@@ -0,0 +1,34 @@
[gd_scene format=3 uid="uid://01m32xxk1ryh"]
[ext_resource type="Script" uid="uid://g2ucwg3k342p" path="res://Peg.cs" id="1_cavuh"]
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_cut4e"]
[ext_resource type="PackedScene" uid="uid://bj2qrn0l01us1" path="res://Pegs/peg_action.tscn" id="3_cavuh"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5
[node name="Peg" type="StaticBody2D" unique_id=1417697759]
input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_cavuh")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
texture_filter = 1
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_cut4e")
[node name="PegAction" parent="." unique_id=637569115 instance=ExtResource("3_cavuh")]
[node name="HoverBounds" type="Area2D" parent="." unique_id=2086452813]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=252175102]
shape = SubResource("CircleShape2D_4gyqm")
[connection signal="mouse_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"]
+6
View File
@@ -0,0 +1,6 @@
[gd_scene format=3 uid="uid://bxlt2ap0dym1x"]
[ext_resource type="Script" path="res://PegController.cs" id="1_31br5"]
[node name="PegController" type="Node2D" unique_id=197453707]
script = ExtResource("1_31br5")
+12 -7
View File
File diff suppressed because one or more lines are too long
+4
View File
@@ -2,8 +2,12 @@
[ext_resource type="Script" uid="uid://cfohujgs5dygx" path="res://PlayerController.cs" id="1_lvefo"]
[ext_resource type="PackedScene" uid="uid://d06n7p75u130s" path="res://tower.tscn" id="2_f0yg5"]
[ext_resource type="PackedScene" uid="uid://b2mb7mimdu5ad" path="res://bucket.tscn" id="3_va7e3"]
[node name="PlayerController" type="Node2D" unique_id=317732890]
script = ExtResource("1_lvefo")
[node name="Tower1" parent="." unique_id=1315831332 instance=ExtResource("2_f0yg5")]
[node name="Bucket" parent="." unique_id=1168722558 instance=ExtResource("3_va7e3")]
position = Vector2(960, 1040)
+5
View File
@@ -51,6 +51,11 @@ changeTurn={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":84,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
middleClick={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":4,"position":Vector2(222, 10),"global_position":Vector2(231, 58),"factor":1.0,"button_index":3,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[physics]
+5 -5
View File
@@ -11,9 +11,9 @@ self_modulate = Color(0, 0, 0, 1)
texture = ExtResource("1_vedim")
script = ExtResource("1_k1sas")
[node name="Area" type="Area2D" parent="." unique_id=620986087]
[node name="HoverBounds" type="Area2D" parent="." unique_id=620986087]
[node name="Bounds" type="CollisionShape2D" parent="Area" unique_id=1639875880]
[node name="CollisionShape2D" type="CollisionShape2D" parent="HoverBounds" unique_id=1639875880]
position = Vector2(0, 0.5)
shape = SubResource("RectangleShape2D_vedim")
debug_color = Color(0.6411928, 0.52469516, 0, 0.41960785)
@@ -21,8 +21,8 @@ debug_color = Color(0.6411928, 0.52469516, 0, 0.41960785)
[node name="Offset" type="Marker2D" parent="." unique_id=2053853274]
position = Vector2(25, -50)
[node name="AttackSpawn" type="Marker2D" parent="." unique_id=715904909]
[node name="BallSpawn" type="Marker2D" parent="." unique_id=715904909]
position = Vector2(0, -24)
[connection signal="mouse_entered" from="Area" to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="Area" to="." method="OnMouseExited"]
[connection signal="mouse_entered" from="HoverBounds" to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="HoverBounds" to="." method="OnMouseExited"]