2024-06-09 00:34:36 +02:00
|
|
|
using Godot;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
2025-03-12 22:01:45 +01:00
|
|
|
using System.Linq;
|
2024-06-09 18:19:57 +02:00
|
|
|
using Cirno.Scripts;
|
2025-02-12 16:20:55 +01:00
|
|
|
using Cirno.Scripts.Resources;
|
2025-03-12 22:01:45 +01:00
|
|
|
using Godot.Collections;
|
2024-06-09 00:34:36 +02:00
|
|
|
|
|
|
|
|
public partial class Barrel : Area2D, IDestructible
|
|
|
|
|
{
|
2025-02-22 19:06:30 +01:00
|
|
|
[Export] public bool Indestructible { get; private set; }
|
2024-06-09 11:45:22 +02:00
|
|
|
[Export] public float Health = 1f;
|
2024-06-09 00:34:36 +02:00
|
|
|
|
2024-06-09 11:45:22 +02:00
|
|
|
[Export] public float ExplosionRadius = 1;
|
2024-06-09 00:34:36 +02:00
|
|
|
|
2024-06-09 11:45:22 +02:00
|
|
|
[Export] public float ExplosionDamage = 1;
|
|
|
|
|
|
|
|
|
|
[Export] public PackedScene DebrisScene { get; set; }
|
2024-06-09 18:19:57 +02:00
|
|
|
|
|
|
|
|
[Export] public PackedScene ExplosionParticles { get; set; }
|
2025-02-12 16:20:55 +01:00
|
|
|
[Export] public BulletResource ExplosionData { get; set; }
|
2025-02-09 21:34:50 +01:00
|
|
|
|
2025-02-15 17:51:06 +01:00
|
|
|
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
2025-03-12 22:01:45 +01:00
|
|
|
[Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
2025-02-15 17:51:06 +01:00
|
|
|
|
2025-02-21 16:27:57 +01:00
|
|
|
[ExportCategory("On Death Activation")]
|
|
|
|
|
[Export]
|
|
|
|
|
public ActivationType ActivationType { get; private set; } = ActivationType.Toggle;
|
|
|
|
|
[Export]
|
|
|
|
|
public Node2D Target { get; private set;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Signal]
|
|
|
|
|
public delegate void ExplodedEventHandler();
|
|
|
|
|
|
2025-02-13 21:55:14 +01:00
|
|
|
private GameManager _gameManager;
|
|
|
|
|
|
2024-06-09 18:19:57 +02:00
|
|
|
private float _currentHealth = 0f;
|
2024-06-09 00:34:36 +02:00
|
|
|
|
|
|
|
|
private bool _isDestroyed = false;
|
|
|
|
|
|
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
|
|
|
public override void _Ready()
|
|
|
|
|
{
|
2025-02-13 21:55:14 +01:00
|
|
|
_gameManager = this.GetGameManager();
|
2024-06-09 00:34:36 +02:00
|
|
|
_currentHealth = Health;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
|
|
|
public override void _Process(double delta)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-09 11:45:22 +02:00
|
|
|
private void Explode()
|
|
|
|
|
{
|
2025-02-09 21:34:50 +01:00
|
|
|
//ApplyExplosionDamage();
|
2025-02-21 16:27:57 +01:00
|
|
|
EmitSignal(SignalName.Exploded, this, _currentHealth);
|
|
|
|
|
ActivateOnDeath();
|
2025-02-09 21:34:50 +01:00
|
|
|
CreateExplosion();
|
2024-06-09 18:19:57 +02:00
|
|
|
CreateParticles();
|
2024-06-09 11:45:22 +02:00
|
|
|
CreateDebris();
|
2025-03-25 13:51:35 +01:00
|
|
|
|
2024-06-09 00:34:36 +02:00
|
|
|
QueueFree();
|
2025-03-25 13:51:35 +01:00
|
|
|
|
2025-04-09 11:43:44 +02:00
|
|
|
GameManager.Instance.RebakeNavigation();
|
2025-03-25 13:51:35 +01:00
|
|
|
//GameManager.Instance.RecalculateTilemap(this.GlobalPosition);
|
2024-06-09 00:34:36 +02:00
|
|
|
}
|
|
|
|
|
|
2025-02-21 16:27:57 +01:00
|
|
|
private void ActivateOnDeath()
|
|
|
|
|
{
|
|
|
|
|
if (Target is IActivable node)
|
|
|
|
|
{
|
|
|
|
|
node.Activate(ActivationType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-09 21:34:50 +01:00
|
|
|
private void CreateExplosion()
|
|
|
|
|
{
|
2025-02-12 16:20:55 +01:00
|
|
|
if (ExplosionData == null) return;
|
2025-02-09 21:34:50 +01:00
|
|
|
|
2025-02-12 16:20:55 +01:00
|
|
|
var explosion = this.CreateSibling<Bullet>(ExplosionData.BulletScene);
|
2025-02-09 21:34:50 +01:00
|
|
|
explosion.Speed = 0;
|
|
|
|
|
|
2025-02-13 21:55:14 +01:00
|
|
|
explosion.Initialize(ExplosionData.MakeBullet(this.GlobalPosition), _gameManager);
|
2025-02-09 21:34:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ApplyExplosionDamage()
|
|
|
|
|
{
|
|
|
|
|
var spaceState = GetWorld2D().DirectSpaceState;
|
|
|
|
|
var query = new PhysicsShapeQueryParameters2D();
|
|
|
|
|
var shape = new CircleShape2D { Radius = ExplosionRadius };
|
|
|
|
|
|
|
|
|
|
query.SetShape(shape);
|
|
|
|
|
query.Transform = new Transform2D(0, GlobalPosition);
|
|
|
|
|
query.CollideWithBodies = false;
|
|
|
|
|
query.CollideWithAreas = true;
|
|
|
|
|
//query.CollisionMask = ;
|
|
|
|
|
|
|
|
|
|
var results = spaceState.IntersectShape(query);
|
|
|
|
|
|
|
|
|
|
GD.Print($"Shapes in range: {results.Count}");
|
|
|
|
|
|
|
|
|
|
foreach (var result in results)
|
|
|
|
|
{
|
|
|
|
|
if (result.TryGetValue("collider", out var colliderObj))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var collider = colliderObj.As<Node2D>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (collider.GetParent<Area2D>() is IDestructible destructible)
|
|
|
|
|
{
|
|
|
|
|
GD.Print($"HITTING {collider.Name}");
|
|
|
|
|
destructible.Hit(ExplosionDamage);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
GD.Print($"Collider {collider.Name} was not idestructible");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-09 11:45:22 +02:00
|
|
|
private void CreateDebris()
|
|
|
|
|
{
|
2025-02-23 19:19:12 +01:00
|
|
|
if (DebrisScene == null) return;
|
2025-01-27 17:13:26 +01:00
|
|
|
this.CreateSibling<Barrel>(DebrisScene);
|
2024-06-09 18:19:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateParticles()
|
|
|
|
|
{
|
2024-08-17 19:11:49 +02:00
|
|
|
if (ExplosionParticles == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-01-27 17:13:26 +01:00
|
|
|
var particle = this.CreateSibling<GpuParticles2D>(ExplosionParticles);
|
2024-06-09 18:19:57 +02:00
|
|
|
if (particle == null) return;
|
|
|
|
|
|
|
|
|
|
particle.Emitting = true;
|
|
|
|
|
|
2024-06-09 11:45:22 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 18:19:57 +02:00
|
|
|
|
2025-02-11 19:00:01 +01:00
|
|
|
public void Hit(float damage, DamageType damageType = DamageType.Neutral)
|
2024-06-09 00:34:36 +02:00
|
|
|
{
|
2025-02-22 19:06:30 +01:00
|
|
|
if (_isDestroyed || Indestructible) return;
|
2024-06-09 11:45:22 +02:00
|
|
|
|
2025-03-12 22:01:45 +01:00
|
|
|
var dmg = DamageResistances.Aggregate(damage, (current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
|
|
|
|
|
|
|
|
|
_currentHealth -= dmg;
|
2025-02-09 21:34:50 +01:00
|
|
|
if (_currentHealth > 0) return;
|
2024-06-09 00:34:36 +02:00
|
|
|
_isDestroyed = true;
|
|
|
|
|
Explode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsDestroyed()
|
|
|
|
|
{
|
|
|
|
|
return _isDestroyed;
|
|
|
|
|
}
|
|
|
|
|
}
|