cirnogodot/Scenes/Barrel.cs

163 lines
4 KiB
C#
Raw Permalink Normal View History

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-06-08 16:33:38 +02:00
using Cirno.Scripts.Controllers;
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-06-08 16:33:38 +02:00
2025-06-17 11:57:59 +02:00
var explosion = PoolingManager.Instance.SpawnBullet<Bullet>(ExplosionData);
2025-06-08 16:33:38 +02:00
explosion.GlobalPosition = this.GlobalPosition;
//var explosion = this.CreateSibling<Bullet>(ExplosionData.BulletScene);
2025-02-09 21:34:50 +01:00
explosion.Speed = 0;
2025-06-19 17:55:23 +02:00
explosion.Initialize(ExplosionData.MakeBullet(this.GlobalPosition));
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()
{
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;
}
}