mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 09:35:34 +00:00
Trenchbroom support for health and destruction
This commit is contained in:
parent
e23d337a16
commit
823886b4ce
19 changed files with 2064 additions and 1398 deletions
|
|
@ -12,122 +12,147 @@ namespace Cirno.Scripts.Actors;
|
|||
[Tool]
|
||||
public partial class Destructible3D : StaticBody3D, IDestructible
|
||||
{
|
||||
[Export] public bool Indestructible { get; private set; }
|
||||
[Export] public float Health = 1f;
|
||||
|
||||
[Export] public bool Indestructible { get; protected set; }
|
||||
[Export] public float Health { get; protected set; } = 1f;
|
||||
|
||||
[Export] public PackedScene DebrisScene { get; set; }
|
||||
|
||||
|
||||
[Export] public PackedScene ExplosionParticles { get; set; }
|
||||
[Export] public BulletResource ExplosionData { get; set; }
|
||||
|
||||
|
||||
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
||||
[Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
||||
|
||||
|
||||
[ExportCategory("On Death Activation")]
|
||||
[Export]
|
||||
public ActivationType ActivationType { get; private set; } = ActivationType.Toggle;
|
||||
[Export]
|
||||
public Node Target { get; private set;}
|
||||
[Export] public string TargetGroup { get; private set; }
|
||||
|
||||
public ActivationType ActivationType { get; protected set; } = ActivationType.Toggle;
|
||||
|
||||
[Export] public Node Target { get; private set; }
|
||||
[Export] public string TargetGroup { get; protected set; }
|
||||
|
||||
[Signal]
|
||||
public delegate void ExplodedEventHandler();
|
||||
|
||||
|
||||
private float _currentHealth = 0f;
|
||||
|
||||
private bool _isDestroyed = false;
|
||||
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_currentHealth = Health;
|
||||
}
|
||||
|
||||
public void _func_godot_apply_properties(Dictionary<string, string> props)
|
||||
|
||||
public virtual void _func_godot_apply_properties(Dictionary<string, Variant> props)
|
||||
{
|
||||
TargetGroup = props["target"];
|
||||
if (props.TryGetValue("activationtype", out var type))
|
||||
{
|
||||
var t = Enum.TryParse(type, true, out ActivationType activationType);
|
||||
if (t)
|
||||
{
|
||||
ActivationType = activationType;
|
||||
}
|
||||
}
|
||||
SetProperties(props);
|
||||
}
|
||||
|
||||
|
||||
protected void SetProperties(Dictionary<string, Variant> props)
|
||||
{
|
||||
if (props.TryGetValue("target", out var target))
|
||||
{
|
||||
TargetGroup = target.AsString();
|
||||
}
|
||||
|
||||
|
||||
if (props.TryGetValue("activationtype", out var type))
|
||||
{
|
||||
var stringType = type.AsString();
|
||||
var t = Enum.TryParse(stringType, true, out ActivationType activationType);
|
||||
if (t)
|
||||
{
|
||||
ActivationType = activationType;
|
||||
}
|
||||
}
|
||||
|
||||
if (props.TryGetValue("indestructible", out var indestructible))
|
||||
{
|
||||
var ind = indestructible.AsBool();
|
||||
Indestructible = ind;
|
||||
}
|
||||
|
||||
if (props.TryGetValue("health", out var health))
|
||||
{
|
||||
var h = health.AsSingle();
|
||||
Health = h;
|
||||
}
|
||||
}
|
||||
|
||||
private void Explode()
|
||||
{
|
||||
//ApplyExplosionDamage();
|
||||
EmitSignal(SignalName.Exploded, this, _currentHealth);
|
||||
ActivateOnDeath();
|
||||
CreateExplosion();
|
||||
CreateParticles();
|
||||
CreateDebris();
|
||||
|
||||
QueueFree();
|
||||
|
||||
//GameManager.Instance.RebakeNavigation();
|
||||
//GameManager.Instance.RecalculateTilemap(this.GlobalPosition);
|
||||
}
|
||||
{
|
||||
//ApplyExplosionDamage();
|
||||
EmitSignal(SignalName.Exploded, this, _currentHealth);
|
||||
ActivateOnDeath();
|
||||
CreateExplosion();
|
||||
CreateParticles();
|
||||
CreateDebris();
|
||||
|
||||
private void ActivateOnDeath()
|
||||
{
|
||||
if (Target is IActivable node)
|
||||
{
|
||||
node.Activate(ActivationType);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(TargetGroup))
|
||||
{
|
||||
ActivationHelper.UseTargets(this, TargetGroup, ActivationType);
|
||||
}
|
||||
}
|
||||
QueueFree();
|
||||
|
||||
private void CreateExplosion()
|
||||
{
|
||||
if (ExplosionData == null) return;
|
||||
|
||||
var explosion = PoolingManager.Instance.SpawnBullet<Bullet3D>(ExplosionData);
|
||||
explosion.GlobalPosition = this.GlobalPosition;
|
||||
|
||||
explosion.Speed = 0;
|
||||
|
||||
explosion.Initialize(ExplosionData.MakeBullet(new Vector2(this.GlobalPosition.X, this.GlobalPosition.Y)));
|
||||
}
|
||||
//GameManager.Instance.RebakeNavigation();
|
||||
//GameManager.Instance.RecalculateTilemap(this.GlobalPosition);
|
||||
}
|
||||
|
||||
private void CreateDebris()
|
||||
{
|
||||
if (DebrisScene == null) return;
|
||||
this.CreateSibling<Destructible3D>(DebrisScene);
|
||||
}
|
||||
private void ActivateOnDeath()
|
||||
{
|
||||
if (Target is IActivable node)
|
||||
{
|
||||
node.Activate(ActivationType);
|
||||
}
|
||||
|
||||
private void CreateParticles()
|
||||
{
|
||||
if (ExplosionParticles == null) {
|
||||
return;
|
||||
}
|
||||
var particle = this.CreateSibling<GpuParticles3D>(ExplosionParticles);
|
||||
if (particle == null) return;
|
||||
if (!string.IsNullOrWhiteSpace(TargetGroup))
|
||||
{
|
||||
ActivationHelper.UseTargets(this, TargetGroup, ActivationType);
|
||||
}
|
||||
}
|
||||
|
||||
particle.Emitting = true;
|
||||
|
||||
}
|
||||
private void CreateExplosion()
|
||||
{
|
||||
if (ExplosionData == null) return;
|
||||
|
||||
var explosion = PoolingManager.Instance.SpawnBullet<Bullet3D>(ExplosionData);
|
||||
explosion.GlobalPosition = this.GlobalPosition;
|
||||
|
||||
explosion.Speed = 0;
|
||||
|
||||
explosion.Initialize(ExplosionData.MakeBullet(new Vector2(this.GlobalPosition.X, this.GlobalPosition.Y)));
|
||||
}
|
||||
|
||||
private void CreateDebris()
|
||||
{
|
||||
if (DebrisScene == null) return;
|
||||
this.CreateSibling<Destructible3D>(DebrisScene);
|
||||
}
|
||||
|
||||
private void CreateParticles()
|
||||
{
|
||||
if (ExplosionParticles == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var particle = this.CreateSibling<GpuParticles3D>(ExplosionParticles);
|
||||
if (particle == null) return;
|
||||
|
||||
particle.Emitting = true;
|
||||
}
|
||||
|
||||
|
||||
public void Hit(float damage, DamageType damageType = DamageType.Neutral)
|
||||
{
|
||||
if (_isDestroyed || Indestructible) return;
|
||||
|
||||
var dmg = DamageResistances.Aggregate(damage, (current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
||||
|
||||
_currentHealth -= dmg;
|
||||
if (_currentHealth > 0) return;
|
||||
_isDestroyed = true;
|
||||
Explode();
|
||||
}
|
||||
public void Hit(float damage, DamageType damageType = DamageType.Neutral)
|
||||
{
|
||||
if (_isDestroyed || Indestructible) return;
|
||||
|
||||
public bool IsDestroyed()
|
||||
{
|
||||
return _isDestroyed;
|
||||
}
|
||||
var dmg = DamageResistances.Aggregate(damage,
|
||||
(current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
||||
|
||||
_currentHealth -= dmg;
|
||||
if (_currentHealth > 0) return;
|
||||
_isDestroyed = true;
|
||||
Explode();
|
||||
}
|
||||
|
||||
public bool IsDestroyed()
|
||||
{
|
||||
return _isDestroyed;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Cirno.Scripts.AttackPatterns;
|
||||
using System;
|
||||
using Cirno.Scripts.AttackPatterns;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.Resources.BulletScripts;
|
||||
using Godot;
|
||||
|
|
@ -7,7 +8,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.Actors;
|
||||
|
||||
[Tool]
|
||||
public partial class ScriptableBulletsEmitter3D : Node3D, IActivable, IScriptHost3D
|
||||
public partial class ScriptableBulletsEmitter3D : Destructible3D, IActivable, IScriptHost3D
|
||||
{
|
||||
public Node3D ParentObject => this;
|
||||
|
||||
|
|
@ -21,6 +22,13 @@ public partial class ScriptableBulletsEmitter3D : Node3D, IActivable, IScriptHos
|
|||
|
||||
[Export]
|
||||
public bool EmitOnStart { get; set; } = false;
|
||||
|
||||
// [Export] public bool Indestructible { get; private set; } = false;
|
||||
// [Export] public float Health = 1f;
|
||||
//
|
||||
// [Export] public BulletResource ExplosionData { get; set; }
|
||||
// [Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
||||
// [Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
||||
|
||||
[Signal]
|
||||
public delegate void StateChangedEventHandler(bool isEmitting);
|
||||
|
|
@ -53,17 +61,26 @@ public partial class ScriptableBulletsEmitter3D : Node3D, IActivable, IScriptHos
|
|||
EmitSignal(SignalName.StateChanged, _isActive);
|
||||
}
|
||||
|
||||
public virtual void _func_godot_apply_properties(Dictionary<string, Variant> props)
|
||||
public override void _func_godot_apply_properties(Dictionary<string, Variant> props)
|
||||
{
|
||||
ActivationGroup = props["targetname"].AsString();
|
||||
|
||||
var scriptPath = props["script_path"].AsString();
|
||||
Script = GD.Load<BulletScript3D>(scriptPath);
|
||||
if (!string.IsNullOrWhiteSpace(scriptPath))
|
||||
{
|
||||
Script = GD.Load<BulletScript3D>(scriptPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PushWarning("Emitter has no script assigned");
|
||||
}
|
||||
|
||||
|
||||
EmitOnStart = props["emit_on_start"].AsBool();
|
||||
InvertSignal = props["invert_signal"].AsBool();
|
||||
//TargetFunc = props["targetfunc"];
|
||||
//TargetName = props["targetname"];
|
||||
SetProperties(props);
|
||||
}
|
||||
|
||||
public bool Activate(ActivationType activationType = ActivationType.Toggle)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue