added forge addon
This commit is contained in:
81
addons/forge/nodes/EffectArea2D.cs
Normal file
81
addons/forge/nodes/EffectArea2D.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://cnjrjkgwyewjx")]
|
||||
public partial class EffectArea2D : Area2D
|
||||
{
|
||||
private EffectApplier? _effectApplier;
|
||||
|
||||
[Export]
|
||||
public Node? EffectOwner { get; set; }
|
||||
|
||||
[Export]
|
||||
public Node? EffectSource { get; set; }
|
||||
|
||||
[Export]
|
||||
public int EffectLevel { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
public EffectTriggerMode TriggerMode { get; set; }
|
||||
|
||||
private IForgeEntity? OwnerEntity => EffectOwner as IForgeEntity;
|
||||
|
||||
private IForgeEntity? SourceEntity => EffectSource as IForgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (EffectOwner is not null && EffectOwner is not IForgeEntity)
|
||||
{
|
||||
GD.PushError($"{nameof(EffectOwner)} must implement {nameof(IForgeEntity)}.");
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
_effectApplier = new EffectApplier(this);
|
||||
|
||||
switch (TriggerMode)
|
||||
{
|
||||
case EffectTriggerMode.OnEnter:
|
||||
BodyEntered += ApplyEffects;
|
||||
AreaEntered += ApplyEffects;
|
||||
break;
|
||||
|
||||
case EffectTriggerMode.OnExit:
|
||||
BodyExited += ApplyEffects;
|
||||
AreaExited += ApplyEffects;
|
||||
break;
|
||||
|
||||
case EffectTriggerMode.OnStay:
|
||||
BodyEntered += AddEffects;
|
||||
AreaEntered += AddEffects;
|
||||
BodyExited += RemoveEffects;
|
||||
AreaExited += RemoveEffects;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffects(Node2D node)
|
||||
{
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
_effectApplier.ApplyEffects(node, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
|
||||
private void AddEffects(Node2D node)
|
||||
{
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
_effectApplier.AddEffects(node, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
|
||||
private void RemoveEffects(Node2D node)
|
||||
{
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
_effectApplier.RemoveEffects(node);
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/EffectArea2D.cs.uid
Normal file
1
addons/forge/nodes/EffectArea2D.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bc8wkfv6rdpu1
|
||||
81
addons/forge/nodes/EffectArea3D.cs
Normal file
81
addons/forge/nodes/EffectArea3D.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://tbuwwf03ikr3")]
|
||||
public partial class EffectArea3D : Area3D
|
||||
{
|
||||
private EffectApplier? _effectApplier;
|
||||
|
||||
[Export]
|
||||
public Node? EffectOwner { get; set; }
|
||||
|
||||
[Export]
|
||||
public Node? EffectSource { get; set; }
|
||||
|
||||
[Export]
|
||||
public int EffectLevel { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
public EffectTriggerMode TriggerMode { get; set; }
|
||||
|
||||
private IForgeEntity? OwnerEntity => EffectOwner as IForgeEntity;
|
||||
|
||||
private IForgeEntity? SourceEntity => EffectSource as IForgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (EffectOwner is not null && EffectOwner is not IForgeEntity)
|
||||
{
|
||||
GD.PushError($"{nameof(EffectOwner)} must implement {nameof(IForgeEntity)}.");
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
_effectApplier = new EffectApplier(this);
|
||||
|
||||
switch (TriggerMode)
|
||||
{
|
||||
case EffectTriggerMode.OnEnter:
|
||||
BodyEntered += ApplyEffects;
|
||||
AreaEntered += ApplyEffects;
|
||||
break;
|
||||
|
||||
case EffectTriggerMode.OnExit:
|
||||
BodyExited += ApplyEffects;
|
||||
AreaExited += ApplyEffects;
|
||||
break;
|
||||
|
||||
case EffectTriggerMode.OnStay:
|
||||
BodyEntered += AddEffects;
|
||||
AreaEntered += AddEffects;
|
||||
BodyExited += RemoveEffects;
|
||||
AreaExited += RemoveEffects;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffects(Node3D node)
|
||||
{
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
_effectApplier.ApplyEffects(node, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
|
||||
private void AddEffects(Node3D node)
|
||||
{
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
_effectApplier.AddEffects(node, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
|
||||
private void RemoveEffects(Node3D node)
|
||||
{
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
_effectApplier.RemoveEffects(node);
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/EffectArea3D.cs.uid
Normal file
1
addons/forge/nodes/EffectArea3D.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cvhkilfepqpyi
|
||||
84
addons/forge/nodes/EffectRayCast2D.cs
Normal file
84
addons/forge/nodes/EffectRayCast2D.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://d3wjawuu1ej3s")]
|
||||
public partial class EffectRayCast2D : RayCast2D
|
||||
{
|
||||
private EffectApplier? _effectApplier;
|
||||
|
||||
private GodotObject? _lastFrameCollider;
|
||||
|
||||
[Export]
|
||||
public Node? EffectOwner { get; set; }
|
||||
|
||||
[Export]
|
||||
public Node? EffectSource { get; set; }
|
||||
|
||||
[Export]
|
||||
public int EffectLevel { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
public EffectTriggerMode TriggerMode { get; set; }
|
||||
|
||||
private IForgeEntity? OwnerEntity => EffectOwner as IForgeEntity;
|
||||
|
||||
private IForgeEntity? SourceEntity => EffectSource as IForgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (EffectOwner is not null && EffectOwner is not IForgeEntity)
|
||||
{
|
||||
GD.PushError($"{nameof(EffectOwner)} must implement {nameof(IForgeEntity)}.");
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
_effectApplier = new EffectApplier(this);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
base._PhysicsProcess(delta);
|
||||
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
|
||||
GodotObject current = GetCollider();
|
||||
var hasCurrent = current is Node;
|
||||
var hadLast = _lastFrameCollider is Node;
|
||||
|
||||
// Enter: is colliding now, wasn't colliding before.
|
||||
if (current is Node currentNode && !hadLast)
|
||||
{
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.AddEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnEnter)
|
||||
{
|
||||
_effectApplier.ApplyEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Exit: Was colliding before, isn't colliding now.
|
||||
if (!hasCurrent && _lastFrameCollider is Node lastNode)
|
||||
{
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.RemoveEffects(lastNode);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnExit)
|
||||
{
|
||||
_effectApplier.ApplyEffects(lastNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
|
||||
_lastFrameCollider = hasCurrent ? current : null;
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/EffectRayCast2D.cs.uid
Normal file
1
addons/forge/nodes/EffectRayCast2D.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://btstkyo5h46w2
|
||||
84
addons/forge/nodes/EffectRayCast3D.cs
Normal file
84
addons/forge/nodes/EffectRayCast3D.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://dskf1b0eecaxl")]
|
||||
public partial class EffectRayCast3D : RayCast3D
|
||||
{
|
||||
private EffectApplier? _effectApplier;
|
||||
|
||||
private GodotObject? _lastFrameCollider;
|
||||
|
||||
[Export]
|
||||
public Node? EffectOwner { get; set; }
|
||||
|
||||
[Export]
|
||||
public Node? EffectSource { get; set; }
|
||||
|
||||
[Export]
|
||||
public int EffectLevel { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
public EffectTriggerMode TriggerMode { get; set; }
|
||||
|
||||
private IForgeEntity? OwnerEntity => EffectOwner as IForgeEntity;
|
||||
|
||||
private IForgeEntity? SourceEntity => EffectSource as IForgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (EffectOwner is not null && EffectOwner is not IForgeEntity)
|
||||
{
|
||||
GD.PushError($"{nameof(EffectOwner)} must implement {nameof(IForgeEntity)}.");
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
_effectApplier = new EffectApplier(this);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
base._PhysicsProcess(delta);
|
||||
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
|
||||
GodotObject current = GetCollider();
|
||||
var hasCurrent = current is Node;
|
||||
var hadLast = _lastFrameCollider is Node;
|
||||
|
||||
// Enter: is colliding now, wasn't colliding before.
|
||||
if (current is Node currentNode && !hadLast)
|
||||
{
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.AddEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnEnter)
|
||||
{
|
||||
_effectApplier.ApplyEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Exit: Was colliding before, isn't colliding now.
|
||||
if (!hasCurrent && _lastFrameCollider is Node lastNode)
|
||||
{
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.RemoveEffects(lastNode);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnExit)
|
||||
{
|
||||
_effectApplier.ApplyEffects(lastNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
|
||||
_lastFrameCollider = hasCurrent ? current : null;
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/EffectRayCast3D.cs.uid
Normal file
1
addons/forge/nodes/EffectRayCast3D.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://7bhjrbrsll5y
|
||||
99
addons/forge/nodes/EffectShapeCast2D.cs
Normal file
99
addons/forge/nodes/EffectShapeCast2D.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://dni75h8pnigh2")]
|
||||
public partial class EffectShapeCast2D : ShapeCast2D
|
||||
{
|
||||
private readonly HashSet<GodotObject> _lastFrameColliders = [];
|
||||
|
||||
private EffectApplier? _effectApplier;
|
||||
|
||||
[Export]
|
||||
public Node? EffectOwner { get; set; }
|
||||
|
||||
[Export]
|
||||
public Node? EffectSource { get; set; }
|
||||
|
||||
[Export]
|
||||
public int EffectLevel { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
public EffectTriggerMode TriggerMode { get; set; }
|
||||
|
||||
private IForgeEntity? OwnerEntity => EffectOwner as IForgeEntity;
|
||||
|
||||
private IForgeEntity? SourceEntity => EffectSource as IForgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (EffectOwner is not null && EffectOwner is not IForgeEntity)
|
||||
{
|
||||
GD.PushError($"{nameof(EffectOwner)} must implement {nameof(IForgeEntity)}.");
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
_effectApplier = new EffectApplier(this);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
base._PhysicsProcess(delta);
|
||||
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
|
||||
var collisions = GetCollisionCount();
|
||||
|
||||
var collidersThisFrame = new List<GodotObject>();
|
||||
for (var i = 0; i < collisions; i++)
|
||||
{
|
||||
GodotObject current = GetCollider(i);
|
||||
var hadLast = _lastFrameColliders.Contains(current);
|
||||
|
||||
_lastFrameColliders.Add(current);
|
||||
collidersThisFrame.Add(current);
|
||||
|
||||
// Enter: is colliding now, wasn't colliding before.
|
||||
if (current is Node currentNode && !hadLast)
|
||||
{
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.AddEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnEnter)
|
||||
{
|
||||
_effectApplier.ApplyEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit: Was colliding before, isn't colliding now.
|
||||
foreach (GodotObject? lastCollider in _lastFrameColliders.Except(collidersThisFrame))
|
||||
{
|
||||
_lastFrameColliders.Remove(lastCollider);
|
||||
|
||||
if (lastCollider is not Node lastNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.RemoveEffects(lastNode);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnExit)
|
||||
{
|
||||
_effectApplier.ApplyEffects(lastNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/EffectShapeCast2D.cs.uid
Normal file
1
addons/forge/nodes/EffectShapeCast2D.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cxrmka1hqkn82
|
||||
99
addons/forge/nodes/EffectShapeCast3D.cs
Normal file
99
addons/forge/nodes/EffectShapeCast3D.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://e2ynjdppura3")]
|
||||
public partial class EffectShapeCast3D : ShapeCast3D
|
||||
{
|
||||
private readonly HashSet<GodotObject> _lastFrameColliders = [];
|
||||
|
||||
private EffectApplier? _effectApplier;
|
||||
|
||||
[Export]
|
||||
public Node? EffectOwner { get; set; }
|
||||
|
||||
[Export]
|
||||
public Node? EffectSource { get; set; }
|
||||
|
||||
[Export]
|
||||
public int EffectLevel { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
public EffectTriggerMode TriggerMode { get; set; }
|
||||
|
||||
private IForgeEntity? OwnerEntity => EffectOwner as IForgeEntity;
|
||||
|
||||
private IForgeEntity? SourceEntity => EffectSource as IForgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (EffectOwner is not null && EffectOwner is not IForgeEntity)
|
||||
{
|
||||
GD.PushError($"{nameof(EffectOwner)} must implement {nameof(IForgeEntity)}.");
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
_effectApplier = new EffectApplier(this);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
base._PhysicsProcess(delta);
|
||||
|
||||
Debug.Assert(_effectApplier is not null, $"{_effectApplier} should have been initialized on _Ready().");
|
||||
|
||||
var collisions = GetCollisionCount();
|
||||
|
||||
var collidersThisFrame = new List<GodotObject>();
|
||||
for (var i = 0; i < collisions; i++)
|
||||
{
|
||||
GodotObject current = GetCollider(i);
|
||||
var hadLast = _lastFrameColliders.Contains(current);
|
||||
|
||||
_lastFrameColliders.Add(current);
|
||||
collidersThisFrame.Add(current);
|
||||
|
||||
// Enter: is colliding now, wasn't colliding before.
|
||||
if (current is Node currentNode && !hadLast)
|
||||
{
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.AddEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnEnter)
|
||||
{
|
||||
_effectApplier.ApplyEffects(currentNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit: Was colliding before, isn't colliding now.
|
||||
foreach (GodotObject? lastCollider in _lastFrameColliders.Except(collidersThisFrame))
|
||||
{
|
||||
_lastFrameColliders.Remove(lastCollider);
|
||||
|
||||
if (lastCollider is not Node lastNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TriggerMode == EffectTriggerMode.OnStay)
|
||||
{
|
||||
_effectApplier.RemoveEffects(lastNode);
|
||||
}
|
||||
else if (TriggerMode == EffectTriggerMode.OnExit)
|
||||
{
|
||||
_effectApplier.ApplyEffects(lastNode, OwnerEntity, SourceEntity, EffectLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/EffectShapeCast3D.cs.uid
Normal file
1
addons/forge/nodes/EffectShapeCast3D.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cd1k8wqsbtpjc
|
||||
21
addons/forge/nodes/EffectTriggerMode.cs
Normal file
21
addons/forge/nodes/EffectTriggerMode.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
public enum EffectTriggerMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Add effects when entering the area.
|
||||
/// </summary>
|
||||
OnEnter = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Add effects when exiting the area.
|
||||
/// </summary>
|
||||
OnExit = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Add effects when entering the area and removes when exiting it.
|
||||
/// </summary>
|
||||
OnStay = 2,
|
||||
}
|
||||
1
addons/forge/nodes/EffectTriggerMode.cs.uid
Normal file
1
addons/forge/nodes/EffectTriggerMode.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://wjgubfjrngpf
|
||||
86
addons/forge/nodes/ForgeAttributeSet.cs
Normal file
86
addons/forge/nodes/ForgeAttributeSet.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Gamesmiths.Forge.Attributes;
|
||||
using Gamesmiths.Forge.Godot.Editor.Attributes;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
[Icon("uid://dnqaqpc02lx3p")]
|
||||
public partial class ForgeAttributeSet : Node
|
||||
{
|
||||
[Export]
|
||||
public string AttributeSetClass { get; set; } = string.Empty;
|
||||
|
||||
[Export]
|
||||
public Dictionary<string, AttributeValues>? InitialAttributeValues { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
InitialAttributeValues ??= [];
|
||||
}
|
||||
|
||||
public AttributeSet? GetAttributeSet()
|
||||
{
|
||||
if (string.IsNullOrEmpty(AttributeSetClass))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Assert(
|
||||
InitialAttributeValues is not null,
|
||||
$"{nameof(InitialAttributeValues)} should have been initialized on _Ready.");
|
||||
|
||||
Type? type = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(x => x.GetTypes())
|
||||
.FirstOrDefault(x => x.Name == AttributeSetClass);
|
||||
|
||||
if (type is null || !typeof(AttributeSet).IsAssignableFrom(type))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var instance = (AttributeSet?)Activator.CreateInstance(type);
|
||||
if (instance is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (PropertyInfo prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (prop.PropertyType == typeof(EntityAttribute))
|
||||
{
|
||||
var name = prop.Name;
|
||||
if (InitialAttributeValues.TryGetValue(name, out AttributeValues? value))
|
||||
{
|
||||
SetAttributeValue("SetAttributeBaseValue", instance, prop, value.Default);
|
||||
SetAttributeValue("SetAttributeMinValue", instance, prop, value.Min);
|
||||
SetAttributeValue("SetAttributeMaxValue", instance, prop, value.Max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static void SetAttributeValue(string methodName, AttributeSet instance, PropertyInfo prop, int value)
|
||||
{
|
||||
#pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
|
||||
// Do not attempt this in production environments without adult supervision.
|
||||
MethodInfo? method = typeof(AttributeSet).GetMethod(
|
||||
methodName,
|
||||
BindingFlags.Static | BindingFlags.NonPublic);
|
||||
#pragma warning restore S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
|
||||
|
||||
method?.Invoke(null, [(EntityAttribute?)prop.GetValue(instance), value]);
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/ForgeAttributeSet.cs.uid
Normal file
1
addons/forge/nodes/ForgeAttributeSet.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cxihb42t2mfqi
|
||||
121
addons/forge/nodes/ForgeCueHandler.cs
Normal file
121
addons/forge/nodes/ForgeCueHandler.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Cues;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Gamesmiths.Forge.Tags;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://snulmvxydrp4")]
|
||||
public abstract partial class ForgeCueHandler : Node, ICueHandler
|
||||
{
|
||||
[Export]
|
||||
public string? CueTag { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base._Ready();
|
||||
|
||||
if (string.IsNullOrEmpty(CueTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ForgeManagers.Instance.CuesManager.RegisterCue(
|
||||
Tag.RequestTag(ForgeManagers.Instance.TagsManager, CueTag), this);
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
base._ExitTree();
|
||||
|
||||
if (string.IsNullOrEmpty(CueTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ForgeManagers.Instance.CuesManager.UnregisterCue(
|
||||
Tag.RequestTag(ForgeManagers.Instance.TagsManager, CueTag), this);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1707, IDE1006, SA1300 // Identifiers should not contain underscores
|
||||
public void OnApply(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
if (target is IForgeEntity forgeEntity)
|
||||
{
|
||||
_CueOnApply(forgeEntity, parameters);
|
||||
}
|
||||
|
||||
_CueOnApply(parameters);
|
||||
}
|
||||
|
||||
public virtual void _CueOnApply(IForgeEntity forgeEntity, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void _CueOnApply(CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
if (target is IForgeEntity forgeEntity)
|
||||
{
|
||||
_CueOnExecute(forgeEntity, parameters);
|
||||
}
|
||||
|
||||
_CueOnExecute(parameters);
|
||||
}
|
||||
|
||||
public virtual void _CueOnExecute(IForgeEntity forgeEntity, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void _CueOnExecute(CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRemove(IForgeEntity? target, bool interrupted)
|
||||
{
|
||||
if (target is IForgeEntity forgeEntity)
|
||||
{
|
||||
_CueOnRemove(forgeEntity, interrupted);
|
||||
}
|
||||
|
||||
_CueOnRemove(interrupted);
|
||||
}
|
||||
|
||||
public virtual void _CueOnRemove(IForgeEntity forgeEntity, bool interrupted)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void _CueOnRemove(bool interrupted)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
if (target is IForgeEntity forgeEntity)
|
||||
{
|
||||
_CueOnUpdate(forgeEntity, parameters);
|
||||
}
|
||||
|
||||
_CueOnUpdate(parameters);
|
||||
}
|
||||
|
||||
public virtual void _CueOnUpdate(IForgeEntity forgeEntity, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void _CueOnUpdate(CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/ForgeCueHandler.cs.uid
Normal file
1
addons/forge/nodes/ForgeCueHandler.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c2b772p0vfde6
|
||||
14
addons/forge/nodes/ForgeEffect.cs
Normal file
14
addons/forge/nodes/ForgeEffect.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using Gamesmiths.Forge.Godot.Resources;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://bpl454nqdpfjx")]
|
||||
public partial class ForgeEffect : Node
|
||||
{
|
||||
[Export]
|
||||
public ForgeEffectData? EffectData { get; set; }
|
||||
}
|
||||
1
addons/forge/nodes/ForgeEffect.cs.uid
Normal file
1
addons/forge/nodes/ForgeEffect.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dps0oef50noil
|
||||
67
addons/forge/nodes/ForgeEntity.cs
Normal file
67
addons/forge/nodes/ForgeEntity.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright © Gamesmiths Guild.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Gamesmiths.Forge.Attributes;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Effects;
|
||||
using Gamesmiths.Forge.Events;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Gamesmiths.Forge.Godot.Resources;
|
||||
using Godot;
|
||||
|
||||
namespace Gamesmiths.Forge.Godot.Nodes;
|
||||
|
||||
[GlobalClass]
|
||||
[Icon("uid://cu6ncpuumjo20")]
|
||||
public partial class ForgeEntity : Node, IForgeEntity
|
||||
{
|
||||
[Export]
|
||||
public ForgeTagContainer BaseTags { get; set; } = new();
|
||||
|
||||
public EntityAttributes Attributes { get; set; } = null!;
|
||||
|
||||
public EntityTags Tags { get; set; } = null!;
|
||||
|
||||
public EffectsManager EffectsManager { get; set; } = null!;
|
||||
|
||||
public EntityAbilities Abilities { get; set; } = null!;
|
||||
|
||||
public EventManager Events { get; set; } = null!;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
Tags = new(BaseTags.GetTagContainer());
|
||||
EffectsManager = new EffectsManager(this, ForgeManagers.Instance.CuesManager);
|
||||
Abilities = new EntityAbilities(this);
|
||||
Events = new EventManager();
|
||||
|
||||
List<AttributeSet> attributeSetList = [];
|
||||
|
||||
foreach (Node node in GetChildren())
|
||||
{
|
||||
if (node is ForgeAttributeSet attributeSetNode)
|
||||
{
|
||||
AttributeSet? attributeSet = attributeSetNode.GetAttributeSet();
|
||||
|
||||
if (attributeSet is not null)
|
||||
{
|
||||
attributeSetList.Add(attributeSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Attributes = new EntityAttributes([.. attributeSetList]);
|
||||
|
||||
var effectApplier = new EffectApplier(this);
|
||||
effectApplier.ApplyEffects(this, this, this);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
|
||||
EffectsManager.UpdateEffects(delta);
|
||||
}
|
||||
}
|
||||
1
addons/forge/nodes/ForgeEntity.cs.uid
Normal file
1
addons/forge/nodes/ForgeEntity.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://8uj04dfe8oql
|
||||
Reference in New Issue
Block a user