Compare commits

...

24 Commits

Author SHA1 Message Date
admin 6cec4b69b7 changing peg disposition so that none = 0 and neutral = -2, will make it easier to sort peg actions later to divide them up by disposition type (will need to delay peg turns by disposition) so that it goes neutral to hostile to friendly. will need to account for this in other methods as well 2026-07-05 03:17:40 -04:00
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
+12 -16
View File
@@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Godot; using Godot;
public partial class Attack : RigidBody2D public partial class Ball : RigidBody2D
{ {
[Signal] [Signal]
public delegate void HitEventHandler(Node NODE); public delegate void HitEventHandler(Node NODE);
@@ -9,7 +9,7 @@ public partial class Attack : RigidBody2D
public delegate void BucketEnteredEventHandler(); public delegate void BucketEnteredEventHandler();
public bool _hovered = false; public bool _hovered = false;
public int _damage = 1; public int _healthChange = -1, _hits = 0;
public Vector2 _speed; public Vector2 _speed;
public Path2D _predictionPath; public Path2D _predictionPath;
public Commander _commanderOwner; public Commander _commanderOwner;
@@ -21,6 +21,16 @@ public partial class Attack : RigidBody2D
_predictionPath = GetNode<Path2D>("PredictedPath"); _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) public override void _PhysicsProcess(double delta)
{ {
base._PhysicsProcess(delta); base._PhysicsProcess(delta);
@@ -49,19 +59,5 @@ public partial class Attack : RigidBody2D
GravityScale = 1; 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] [Signal]
public delegate void AttackEnteredEventHandler(Attack ATTACK); public delegate void BallEnteredEventHandler(Ball BALL);
public int _minX = -500, _maxX = 500, _movementSign = 1, _movementSpeed = 3; public int _minX = -500, _maxX = 500, _movementSign = 1, _movementSpeed = 3;
public Vector2 _startPoisition; public Vector2 _startPoisition;
@@ -27,10 +27,10 @@ public partial class Bucket : Node2D
} }
public void OnBodyEntered(Node2D BODY) public void OnBodyEntered(Node2D BODY)
{ {
if (BODY is Attack attack) if (BODY is Ball ball)
{ {
EmitSignal(SignalName.AttackEntered, attack); EmitSignal(SignalName.BallEntered, ball);
attack.EnteredBucket(); ball.EnteredBucket();
} }
} }
} }
+20 -20
View File
@@ -6,18 +6,18 @@ public partial class Commander : Sprite2D
[Signal] [Signal]
public delegate void ActionsUpEventHandler(); public delegate void ActionsUpEventHandler();
public int _actionsMax = 1, _actions; public int _actionsMax = 1, _actions;
public PackedScene _attackScene = GD.Load<PackedScene>("res://Attack.tscn"); public PackedScene _ballScene = GD.Load<PackedScene>("res://Ball.tscn");
public Attack _attack; public Ball _ball;
public PlayerController _playerController; public PlayerController _playerController;
public override void _Process(double delta) public override void _Process(double delta)
{ {
base._Process(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) if (_actions <= 0)
{ {
EmitSignal(SignalName.ActionsUp); EmitSignal(SignalName.ActionsUp);
@@ -26,34 +26,34 @@ public partial class Commander : Sprite2D
} }
} }
public void AttackEnteredBucket() public void BallEnteredBucket()
{ {
_actions += (_actions + 1) > _actionsMax ? 0 : 1; _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>(); _ball = _ballScene.Instantiate<Ball>();
_attack.Position = OFFSET; _ball.Position = OFFSET;
_attack._commanderOwner = this; _ball._commanderOwner = this;
_attack.GravityScale = 0; _ball.GravityScale = 0;
_attack.BucketEntered += AttackEnteredBucket; _ball.BucketEntered += BallEnteredBucket;
AddChild(_attack); AddChild(_ball);
} }
} }
public void ShootCurrentAttack(Vector2 FORCE){ public void ShootCurrentBall(Vector2 FORCE){
_attack.Shoot(FORCE); _ball.Shoot(FORCE);
_actions--; _actions--;
} }
public void UnloadAttack() public void UnloadBall()
{ {
_attack.QueueFree(); _ball.QueueFree();
_attack = null; _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 Godot;
using System; using System;
using System.Collections.Generic;
public partial class Globals : Node public partial class Globals : Node2D
{ {
public static Random _rng = new(); 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 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 PlayArea _playArea;
public PlayerController _playerController; public PlayerController _playerController;
public EnemyController _enemyController; public PegController _pegController;
public TurnController _turnController; public TurnController _turnController;
public Random _rng = new(); public Random _rng = new();
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
Globals._mouse = GetNode<MouseHandler>("MouseHandler");
_playArea = GetNode<PlayArea>("PlayArea"); _playArea = GetNode<PlayArea>("PlayArea");
_playerController = GetNode<PlayerController>("PlayerController"); _playerController = GetNode<PlayerController>("PlayerController");
_enemyController = GetNode<EnemyController>("EnemyController"); _pegController = GetNode<PegController>("PegController");
_playerController._enemyController = _enemyController; _playerController._pegController = _pegController;
_enemyController._playerController = _playerController; _pegController._playerController = _playerController;
_playerController._playArea = _playArea; _playerController._playArea = _playArea;
_enemyController._playArea = _playArea; _pegController._playArea = _playArea;
_playerController._map = _playArea._map;
_pegController._map = _playArea._map;
_playerController.TurnDone += ChangeTurn; _playerController.TurnDone += ChangeTurn;
_playerController.Death += EndGame; _playerController.Death += EndGame;
_enemyController.TurnDone += ChangeTurn; _pegController.TurnDone += ChangeTurn;
_enemyController.Initiate(); _pegController.Initiate();
_playerController.SetUpTowers(); _playerController.SetUpTowers();
ChangeTurn(); ChangeTurn();
} }
@@ -43,24 +46,15 @@ public partial class Main : Node
{ {
if(_turnController == _playerController) if(_turnController == _playerController)
{ {
ChangeTurn(); _playerController.EndTurn();
} }
} }
} }
public async void ChangeTurn() public void ChangeTurn()
{ {
_turnController = _turnController == _playerController ? _pegController : _playerController;
if (_turnController != _playerController) _turnController.StartTurn();
{
_turnController = _playerController;
await _playerController.StartTurn();
}
else
{
_turnController = _enemyController;
await _enemyController.StartTurn();
}
} }
public void EndGame(PlayerController PLAYER) public void EndGame(PlayerController PLAYER)
+111 -50
View File
@@ -3,31 +3,97 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Dynamic; using System.Dynamic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata.Ecma335;
public partial class Map : TileMapLayer public partial class Map : TileMapLayer
{ {
public PackedScene _mapCellScene = GD.Load<PackedScene>("res://map_cell.tscn");
public int _minX, _maxX, _minY, _maxY, _mainSource = 0; 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 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 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() public override void _Ready()
{ {
base._Ready(); base._Ready();
// GD.Print(GlobalPosition);
List<Vector2I> usedCells = [.. GetUsedCells()];
_cellSize = TileSet.TileSize; _cellSize = TileSet.TileSize;
_cells = [.. GetUsedCells()]; for (int i = 0; i < usedCells.Count; i++)
_cells.ForEach(c => _addressOccupants[c] = null); {
_minX = _cells.Min(c => c.X); MapCell newMapCell = _mapCellScene.Instantiate<MapCell>();
_maxX = _cells.Max(c => c.X); Vector2I usedCell = usedCells[i];
_minY = _cells.Min(c => c.Y); newMapCell._address = usedCell;
_maxY = _cells.Max(c => c.Y); newMapCell.GlobalPosition = newMapCell._address * _cellSize + _cellSize / 2;
_leftmostColumn = [.. _cells.Where(c => c.X == _minX)]; // GD.Print(GlobalPosition, newMapCell.GlobalPosition);
_rightmostColumn = [.. _cells.Where(c => c.X == _maxX)]; newMapCell._occupant = null;
_topRow = [.. _cells.Where(c => c.Y == _minY)]; _cells[usedCell] = newMapCell;
_bottomRow = [.. _cells.Where(c => c.Y == _maxY)]; 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); _sizeInCells = new Vector2(_topRow.Count, _leftmostColumn.Count);
_sizeInPixels = _sizeInCells * _cellSize; _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)); 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++) return _cells[CELL_TO_CHECK]._occupant;
{
if (!IsRowFull(i))
{
return i;
}
}
return 1;
}
public Enemy GetOccupant(Vector2I CELL_TO_CHECK)
{
return _addressOccupants[CELL_TO_CHECK];
} }
public bool HasOccupant(Vector2I CELL_TO_CHECK) public bool HasOccupant(Vector2I CELL_TO_CHECK)
@@ -82,33 +137,39 @@ public partial class Map : TileMapLayer
return hasOccupant || isSolid; 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) 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; PEG._cell._occupant = null;
SetCellSolid(ENEMY._address); SetCellSolid(_cells[PEG._address]);
} }
ENEMY._address = ADDRESS; PEG._cell = CELL;
PEG._address = CELL._address;
}
CELL._occupant = PEG;
SetCellSolid(CELL);
} }
public void SetCellSolid(MapCell CELL)
_addressOccupants[ADDRESS] = ENEMY;
SetCellSolid(ADDRESS);
}
public void SetCellSolid(Vector2I ADDRESS)
{ {
_astar.SetPointSolid(ADDRESS, IsCellSolid(ADDRESS)); _astar.SetPointSolid(CELL._address, IsCellSolid(CELL._address));
// _astar.SetPointWeightScale(ADDRESS, IsCellSolid(ADDRESS) ? 1000 : 1); // _astar.SetPointWeightScale(ADDRESS, IsCellSolid(ADDRESS) ? 1000 : 1);
} }
@@ -121,16 +182,16 @@ public partial class Map : TileMapLayer
_astar.Update(); _astar.Update();
for (int i = 0; i < _cells.Count; i++) 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(); 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); _astar.SetPointSolid(FROM, false);
List<Vector2I> pathTaken = [.. _astar.GetIdPath(FROM, TO, true)]; List<Vector2I> pathTaken = [.. _astar.GetIdPath(FROM, TO, PARTIAL)];
_astar.SetPointSolid(FROM, true); _astar.SetPointSolid(FROM, true);
if (!INCLUDE_FROM) if (!INCLUDE_FROM)
@@ -144,7 +205,7 @@ public partial class Map : TileMapLayer
{ {
for (int i = 0; i < _cells.Count; i++) 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="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"] [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) texture_region_size = Vector2i(40, 40)
0:0/0 = 0 0:0/0 = 0
1:0/0 = 0 1:0/0 = 0
1:0/0/custom_data_1 = -1
2:0/0 = 0 2:0/0 = 0
2:0/0/custom_data_1 = 1
3:0/0 = 0 3:0/0 = 0
3:0/0/custom_data_0 = true 3:0/0/custom_data_0 = true
4:0/0 = 0 4:0/0 = 0
@@ -26,6 +28,8 @@ texture_region_size = Vector2i(40, 40)
tile_size = Vector2i(40, 40) tile_size = Vector2i(40, 40)
custom_data_layer_0/name = "is_solid" custom_data_layer_0/name = "is_solid"
custom_data_layer_0/type = 1 custom_data_layer_0/type = 1
custom_data_layer_1/name = "disposition"
custom_data_layer_1/type = 2
sources/1 = SubResource("TileSetAtlasSource_trj13") sources/1 = SubResource("TileSetAtlasSource_trj13")
pattern_0 = SubResource("TileMapPattern_fjt81") 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 = 0,
FRIENDLY = 1,
HOSTILE = -1,
NEUTRAL = -2
}
}
+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="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="1_7k104"] [ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_0icqg"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7k104"]
bounce = 0.5 bounce = 0.5
@@ -9,17 +9,28 @@ bounce = 0.5
[sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"] [sub_resource type="CircleShape2D" id="CircleShape2D_4gyqm"]
radius = 12.5 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 input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_7k104") physics_material_override = SubResource("PhysicsMaterial_7k104")
script = ExtResource("1_4gyqm") script = ExtResource("1_nc8fp")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899] [node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1762191899]
shape = SubResource("CircleShape2D_4gyqm") shape = SubResource("CircleShape2D_4gyqm")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605] [node name="Sprite2D" type="Sprite2D" parent="." unique_id=1941012605]
texture_filter = 1
scale = Vector2(0.5, 0.5) 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_entered" from="." to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="." to="." method="OnMouseExited"] [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 Node2D _leftEdge, _rightEdge;
public Area2D _region; public Area2D _region;
public Map _map; public Map _map;
public Bucket _bucket;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_bucket = GetNode<Bucket>("Bucket");
_region = GetNode<Area2D>("Region"); _region = GetNode<Area2D>("Region");
_leftEdge = GetNode<Node2D>("LeftEdge"); _leftEdge = GetNode<Node2D>("LeftEdge");
@@ -23,33 +21,32 @@ public partial class PlayArea : Node2D
_map = GetNode<Map>("Map"); _map = GetNode<Map>("Map");
TileMapLayer occupiedSpaces = GetNode<TileMapLayer>("OccupiedSpaces"); TileMapLayer occupiedSpaces = GetNode<TileMapLayer>("OccupiedSpaces");
occupiedSpaces.SetCell(Vector2I.Zero, 0, new Vector2I(4,0));
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
base._Process(delta); base._Process(delta);
_bucket.Move();
} }
public void HighlightCells() public void HighlightCells()
{ {
TileMapLayer occupiedSpaces = GetNode<TileMapLayer>("OccupiedSpaces"); 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 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] [Signal]
public delegate void DeathEventHandler(PlayerController THIS); public delegate void DeathEventHandler(PlayerController THIS);
public bool _dead = false; public bool _dead = false;
public int _health, _healthMax = 100; public int _health, _healthMax = 100, _gold = 0;
public EnemyController _enemyController; public PegController _pegController;
public PackedScene _commanderScene = GD.Load<PackedScene>("res://Commander.tscn"); public PackedScene _commanderScene = GD.Load<PackedScene>("res://Commander.tscn");
public List<Tower> _towers = new(); public List<Tower> _towers = new();
public Bucket _bucket;
public override void _Ready() public override void _Ready()
{ {
_health = _healthMax; _health = _healthMax;
base._Ready(); 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) public void ChangeHealth(int DAMAGE, Node IMPETUS = null)
{ {
_health += DAMAGE; _health += DAMAGE;
@@ -63,7 +72,7 @@ public partial class PlayerController : TurnController
_towers[3].AddChild(newCommander); _towers[3].AddChild(newCommander);
} }
public override async Task StartTurn() public override void StartTurn()
{ {
_towers.ForEach(t => t.StartTurn()); _towers.ForEach(t => t.StartTurn());
} }
+13 -19
View File
@@ -3,22 +3,22 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; 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 int _launchSpeed = 1000, _arcIterations = 50;
public Vector2 _aimOffset, _arcEnd; public Vector2 _aimOffset, _arcEnd;
public List<Vector2> _arc = new(); public List<Vector2> _arc = new();
public Marker2D _offset, _attackSpawn; public Marker2D _offset, _ballSpawn;
public Area2D _area; public Area2D _area;
public Commander _commander; public Commander _commander;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_area = GetNode<Area2D>("Area");
_offset = GetNode<Marker2D>("Offset"); _offset = GetNode<Marker2D>("Offset");
_attackSpawn = GetNode<Marker2D>("AttackSpawn"); _ballSpawn = GetNode<Marker2D>("BallSpawn");
// Click += HandleClick;
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
@@ -29,19 +29,19 @@ public partial class Tower : Sprite2D
{ {
if (_arcEnd != GetGlobalMousePosition()) if (_arcEnd != GetGlobalMousePosition())
{ {
DrawArc(_attackSpawn.GlobalPosition, GetGlobalMousePosition()); DrawArc(_ballSpawn.GlobalPosition, GetGlobalMousePosition());
} }
if (Input.IsActionJustPressed("rightClick")) if (Input.IsActionJustPressed("rightClick"))
{ {
_commander.UnloadAttack(); _commander.UnloadBall();
_aiming = false; _aiming = false;
} }
else if (Input.IsActionJustPressed("leftClick")) else if (Input.IsActionJustPressed("leftClick"))
{ {
_aimOffset = ToLaunchVector(CalculateLaunchAngle(_attackSpawn.GlobalPosition, GetGlobalMousePosition())); _aimOffset = ToLaunchVector(CalculateLaunchAngle(_ballSpawn.GlobalPosition, GetGlobalMousePosition()));
_commander.ShootCurrentAttack(_aimOffset); _commander.ShootCurrentBall(_aimOffset);
ClearArc(); ClearArc();
_aiming = false; _aiming = false;
@@ -52,10 +52,11 @@ public partial class Tower : Sprite2D
if (Input.IsActionJustPressed("leftClick")) if (Input.IsActionJustPressed("leftClick"))
{ {
_aiming = true; _aiming = true;
_commander.LoadAttack(_attackSpawn.Position); _commander.LoadBall(_ballSpawn.Position);
} }
} }
} }
} }
public float CalculateLaunchAngle(Vector2 START, Vector2 END, int MAX_ITERATIONS = 20) public float CalculateLaunchAngle(Vector2 START, Vector2 END, int MAX_ITERATIONS = 20)
@@ -111,7 +112,7 @@ public partial class Tower : Sprite2D
public void ClearArc() public void ClearArc()
{ {
Path2D path = _commander._attack.GetNode<Path2D>("PredictedPath"); Path2D path = _commander._ball.GetNode<Path2D>("PredictedPath");
path.Curve.ClearPoints(); 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(); path.Curve.ClearPoints();
for (int i = 0; i < arc.Count; i++) for (int i = 0; i < arc.Count; i++)
@@ -192,11 +193,4 @@ public partial class Tower : Sprite2D
return Vector2.FromAngle(ANGLE) * _launchSpeed; 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] [Signal]
public delegate void TurnDoneEventHandler(); public delegate void TurnDoneEventHandler();
public PlayArea _playArea; public PlayArea _playArea;
public Map _map;
public virtual async Task StartTurn() public virtual void StartTurn()
{ {
} }
+7 -5
View File
@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://cevk7yax5tvej"] [gd_scene format=3 uid="uid://cevk7yax5tvej"]
[ext_resource type="Script" uid="uid://dm2gyxmgwbmg8" path="res://Attack.cs" id="1_63pi1"] [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_hqc8w"] [ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_ktgx5"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_63pi1"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_63pi1"]
bounce = 0.25 bounce = 0.25
@@ -11,19 +11,21 @@ radius = 12.5
[sub_resource type="Curve2D" id="Curve2D_63pi1"] [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 input_pickable = true
physics_material_override = SubResource("PhysicsMaterial_63pi1") physics_material_override = SubResource("PhysicsMaterial_63pi1")
contact_monitor = true contact_monitor = true
max_contacts_reported = 100 max_contacts_reported = 100
script = ExtResource("1_63pi1") script = ExtResource("1_41u45")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1448070524] [node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1448070524]
shape = SubResource("CircleShape2D_7yfhp") shape = SubResource("CircleShape2D_7yfhp")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1583277900] [node name="Sprite2D" type="Sprite2D" parent="." unique_id=1583277900]
scale = Vector2(0.5, 0.5) 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] [node name="PredictedPath" type="Path2D" parent="." unique_id=1505290715]
modulate = Color(1, 0, 1, 1) 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="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://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" 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] [node name="Main" type="Node" unique_id=535208469]
script = ExtResource("1_ig7tw") script = ExtResource("1_ig7tw")
@@ -11,6 +12,8 @@ script = ExtResource("1_ig7tw")
[node name="PlayArea" parent="." unique_id=1123610167 instance=ExtResource("2_1bvp3")] [node name="PlayArea" parent="." unique_id=1123610167 instance=ExtResource("2_1bvp3")]
position = Vector2(360, 180) 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="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="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://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] [node name="PlayerController" type="Node2D" unique_id=317732890]
script = ExtResource("1_lvefo") script = ExtResource("1_lvefo")
[node name="Tower1" parent="." unique_id=1315831332 instance=ExtResource("2_f0yg5")] [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) "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] [physics]
+5 -5
View File
@@ -11,9 +11,9 @@ self_modulate = Color(0, 0, 0, 1)
texture = ExtResource("1_vedim") texture = ExtResource("1_vedim")
script = ExtResource("1_k1sas") 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) position = Vector2(0, 0.5)
shape = SubResource("RectangleShape2D_vedim") shape = SubResource("RectangleShape2D_vedim")
debug_color = Color(0.6411928, 0.52469516, 0, 0.41960785) 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] [node name="Offset" type="Marker2D" parent="." unique_id=2053853274]
position = Vector2(25, -50) 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) position = Vector2(0, -24)
[connection signal="mouse_entered" from="Area" to="." method="OnMouseEntered"] [connection signal="mouse_entered" from="HoverBounds" to="." method="OnMouseEntered"]
[connection signal="mouse_exited" from="Area" to="." method="OnMouseExited"] [connection signal="mouse_exited" from="HoverBounds" to="." method="OnMouseExited"]