♻️ Optimizations of the various system
🍱 Retexture of the enemy portal
This commit is contained in:
@@ -69,7 +69,7 @@ public partial class BaseTile : Node2D
|
||||
public virtual bool TakeDamage(int damage)
|
||||
{
|
||||
if (IsDestroyed || IsConstructing) return false;
|
||||
|
||||
|
||||
GD.Print($"[Tile] {TileId} {GetInstanceId()} took {damage} damage");
|
||||
|
||||
CurrentDurability = Mathf.Max(0, CurrentDurability - damage);
|
||||
@@ -136,6 +136,9 @@ public partial class BaseTile : Node2D
|
||||
protected virtual void OnTileDestroyed()
|
||||
{
|
||||
// Can be overridden by derived classes for custom destruction behavior
|
||||
var cell = GridUtils.WorldToGrid(Position);
|
||||
var buildingInfo = Registry.GetBuilding(TileId);
|
||||
Grid.FreeArea(cell, buildingInfo.Size, Rotation, buildingInfo.Layer);
|
||||
}
|
||||
|
||||
// Building progress visualization
|
||||
|
@@ -1,77 +0,0 @@
|
||||
using AceFieldNewHorizon.Scripts.Entities;
|
||||
using Godot;
|
||||
|
||||
namespace AceFieldNewHorizon.Scripts.Tiles;
|
||||
|
||||
public partial class EnemyNestTile : BaseTile
|
||||
{
|
||||
[Export] public PackedScene EnemyScene;
|
||||
[Export] public int MaxEnemies = 5;
|
||||
[Export] public float SpawnDelay = 5.0f; // Time between spawn attempts
|
||||
[Export] public float SpawnRadius = 50.0f; // Radius around the nest where enemies can spawn
|
||||
[Export] public bool Active = true;
|
||||
|
||||
private Timer _spawnTimer;
|
||||
private int _currentEnemyCount = 0;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
// Add to Hostile group to prevent enemies from attacking their own nest
|
||||
AddToGroup("Hostile");
|
||||
|
||||
// Create and configure the timer
|
||||
_spawnTimer = new Timer
|
||||
{
|
||||
Autostart = true,
|
||||
WaitTime = SpawnDelay
|
||||
};
|
||||
AddChild(_spawnTimer);
|
||||
_spawnTimer.Timeout += OnSpawnTimerTimeout;
|
||||
}
|
||||
|
||||
private void OnSpawnTimerTimeout()
|
||||
{
|
||||
if (!Active || EnemyScene == null || _currentEnemyCount >= MaxEnemies)
|
||||
return;
|
||||
|
||||
// Check if we can spawn more enemies
|
||||
var enemies = GetTree().GetNodesInGroup("Enemy");
|
||||
_currentEnemyCount = enemies.Count;
|
||||
|
||||
if (_currentEnemyCount >= MaxEnemies)
|
||||
return;
|
||||
|
||||
// Spawn a new enemy
|
||||
var enemy = EnemyScene.Instantiate<Enemy>();
|
||||
if (enemy != null)
|
||||
{
|
||||
GetParent().AddChild(enemy);
|
||||
|
||||
// Calculate a random position within the spawn radius
|
||||
var randomAngle = GD.Randf() * Mathf.Pi * 2;
|
||||
var randomOffset = new Vector2(
|
||||
Mathf.Cos(randomAngle) * SpawnRadius,
|
||||
Mathf.Sin(randomAngle) * SpawnRadius
|
||||
);
|
||||
|
||||
enemy.GlobalPosition = GlobalPosition + randomOffset;
|
||||
_currentEnemyCount++;
|
||||
|
||||
// Connect to the enemy's death signal if available
|
||||
enemy.TreeExiting += () => OnEnemyDied();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnemyDied()
|
||||
{
|
||||
_currentEnemyCount = Mathf.Max(0, _currentEnemyCount - 1);
|
||||
}
|
||||
|
||||
public void SetActive(bool active)
|
||||
{
|
||||
Active = active;
|
||||
_spawnTimer.Paused = !active;
|
||||
}
|
||||
}
|
129
Scripts/Tiles/EnemyPortalTile.cs
Normal file
129
Scripts/Tiles/EnemyPortalTile.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using AceFieldNewHorizon.Scripts.Entities;
|
||||
using Godot;
|
||||
|
||||
namespace AceFieldNewHorizon.Scripts.Tiles;
|
||||
|
||||
public partial class EnemyPortalTile : BaseTile
|
||||
{
|
||||
[Export] public PackedScene EnemyScene;
|
||||
[Export] public int MaxEnemies = 5;
|
||||
[Export] public float SpawnDelay = 5.0f; // Time between spawn attempts
|
||||
[Export] public float SpawnRadius = 50.0f; // Radius around the nest where enemies can spawn
|
||||
[Export] public bool Active = true;
|
||||
|
||||
private Timer _spawnTimer;
|
||||
private int _currentEnemyCount = 0;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
// Add to Hostile group to prevent enemies from attacking their own nest
|
||||
AddToGroup("Hostile");
|
||||
|
||||
// Create and configure the timer
|
||||
_spawnTimer = new Timer
|
||||
{
|
||||
Autostart = true,
|
||||
WaitTime = SpawnDelay
|
||||
};
|
||||
AddChild(_spawnTimer);
|
||||
_spawnTimer.Timeout += OnSpawnTimerTimeout;
|
||||
|
||||
var sprite = GetNode<Sprite2D>("Sprite2D");
|
||||
|
||||
// Create and configure the shadow sprite
|
||||
var shadow = new Sprite2D
|
||||
{
|
||||
Texture = sprite.Texture,
|
||||
Scale = sprite.Scale * 1.05f, // Slightly larger than the original
|
||||
Modulate = new Color(0, 0, 0, 0.5f), // Slightly more transparent
|
||||
Position = new Vector2(0, 12), // Closer to the sprite (reduced from 30)
|
||||
ZIndex = -1
|
||||
};
|
||||
AddChild(shadow);
|
||||
|
||||
// Create floating animation
|
||||
const float floatOffset = 5.0f;
|
||||
const float floatDuration = 2.0f;
|
||||
|
||||
var tween = CreateTween().SetLoops();
|
||||
tween.TweenProperty(sprite, "position:y", -floatOffset, floatDuration)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine);
|
||||
tween.TweenProperty(sprite, "position:y", floatOffset, floatDuration * 2)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine);
|
||||
tween.TweenProperty(sprite, "position:y", 0, floatDuration)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine);
|
||||
|
||||
// Animate shadow
|
||||
tween.Parallel().TweenProperty(shadow, "position:y", 12 - (floatOffset * 0.3f), floatDuration)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine);
|
||||
tween.Parallel().TweenProperty(shadow, "scale", sprite.Scale * 1.02f, floatDuration)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine);
|
||||
tween.Parallel().TweenProperty(shadow, "modulate:a", 0.6f, floatDuration)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine);
|
||||
|
||||
tween.Parallel().TweenProperty(shadow, "position:y", 12 + (floatOffset * 0.4f), floatDuration * 2)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine)
|
||||
.SetDelay(floatDuration);
|
||||
tween.Parallel().TweenProperty(shadow, "scale", sprite.Scale * 1.08f, floatDuration * 2)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine)
|
||||
.SetDelay(floatDuration);
|
||||
tween.Parallel().TweenProperty(shadow, "modulate:a", 0.4f, floatDuration * 2)
|
||||
.SetEase(Tween.EaseType.InOut)
|
||||
.SetTrans(Tween.TransitionType.Sine)
|
||||
.SetDelay(floatDuration);
|
||||
}
|
||||
|
||||
private void OnSpawnTimerTimeout()
|
||||
{
|
||||
if (!Active || EnemyScene == null || _currentEnemyCount >= MaxEnemies)
|
||||
return;
|
||||
|
||||
// Check if we can spawn more enemies
|
||||
var enemies = GetTree().GetNodesInGroup("Enemy");
|
||||
_currentEnemyCount = enemies.Count;
|
||||
|
||||
if (_currentEnemyCount >= MaxEnemies)
|
||||
return;
|
||||
|
||||
// Spawn a new enemy
|
||||
var enemy = EnemyScene.Instantiate<Enemy>();
|
||||
if (enemy != null)
|
||||
{
|
||||
GetParent().AddChild(enemy);
|
||||
|
||||
// Calculate a random position within the spawn radius
|
||||
var randomAngle = GD.Randf() * Mathf.Pi * 2;
|
||||
var randomOffset = new Vector2(
|
||||
Mathf.Cos(randomAngle) * SpawnRadius,
|
||||
Mathf.Sin(randomAngle) * SpawnRadius
|
||||
);
|
||||
|
||||
enemy.GlobalPosition = GlobalPosition + randomOffset;
|
||||
_currentEnemyCount++;
|
||||
|
||||
// Connect to the enemy's death signal if available
|
||||
enemy.TreeExiting += () => OnEnemyDied();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnemyDied()
|
||||
{
|
||||
_currentEnemyCount = Mathf.Max(0, _currentEnemyCount - 1);
|
||||
}
|
||||
|
||||
public void SetActive(bool active)
|
||||
{
|
||||
Active = active;
|
||||
_spawnTimer.Paused = !active;
|
||||
}
|
||||
}
|
@@ -8,6 +8,7 @@ public partial class GroundTile : BaseTile
|
||||
{
|
||||
var sprite = GetNode<Sprite2D>("Sprite2D");
|
||||
sprite.Modulate = new Color(0.75f, 0.75f, 0.75f); // Makes the sprite 25% darker
|
||||
sprite.ZIndex = -10;
|
||||
|
||||
base._Ready();
|
||||
}
|
||||
|
Reference in New Issue
Block a user