atomic pair - purchasing couples them, so neither moves alone. SkillData.Level is gone. It was an [Export] on a cached Resource: one instance per process, so the level never persisted, leaked between save slots, and made "unowned" indistinguishable from "level 1". Level now comes from the Playthrough and is passed to ISkill.Initialize. SkillManager reconciles from SkillSetChanged instead of being told by each caller. The old shape was "record it, then tell SkillManager" as two calls at four sites; AddSkill's early return when no player is registered left the skill owned but inert. Reconciliation also tracks the level each component was built at, so an upgrade rebuilds it rather than being patched in from outside. SkillUnlockerComponent collapses to one TryBuy - unlock and upgrade were two methods each doing affordability, debit, level mutation and manager notification in order. The guard three components copy-pasted around Upgrades[Level - 1] - and which BrickArmor omitted - now lives once in SkillComponentBase. Hud reads coins from CoinsChanged instead of rebuilding translated strings every frame. Lives still polls; it moves with the death path.
127 lines
3.4 KiB
C#
127 lines
3.4 KiB
C#
using System;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
using Mr.BrickAdventures.scripts.interfaces;
|
|
using Mr.BrickAdventures.scripts.Resources;
|
|
|
|
namespace Mr.BrickAdventures.scripts.components;
|
|
|
|
[GlobalClass]
|
|
public partial class MagneticSkillComponent : SkillComponentBase
|
|
{
|
|
[Export] public Area2D MagneticArea { get; set; }
|
|
[Export] public float MagneticMoveDuration { get; set; } = 1.25f;
|
|
|
|
private Array<Node2D> _collectablesToPickUp = [];
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
foreach (var collectable in _collectablesToPickUp)
|
|
{
|
|
if (!IsInstanceValid(collectable))
|
|
{
|
|
_collectablesToPickUp.Remove(collectable);
|
|
continue;
|
|
}
|
|
|
|
MoveCollectableToOwner(collectable);
|
|
}
|
|
}
|
|
|
|
private void OnBodyEntered(Node2D body)
|
|
{
|
|
if (!HasComponentInChildren(body, "CollectableComponent")) return;
|
|
|
|
if (_collectablesToPickUp.Contains(body)) return;
|
|
_collectablesToPickUp.Add(body);
|
|
}
|
|
|
|
private void OnAreaEntered(Area2D area)
|
|
{
|
|
if (!HasComponentInChildren(area, "CollectableComponent")) return;
|
|
|
|
if (_collectablesToPickUp.Contains(area)) return;
|
|
_collectablesToPickUp.Add(area);
|
|
}
|
|
|
|
private bool HasComponentInChildren(Node node, string componentName)
|
|
{
|
|
if (node == null) return false;
|
|
|
|
if (node.HasNode(componentName)) return true;
|
|
|
|
foreach (var child in node.GetChildren())
|
|
{
|
|
if (child is { } childNode && HasComponentInChildren(childNode, componentName))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void MoveCollectableToOwner(Node2D collectable)
|
|
{
|
|
if (!IsInstanceValid(collectable) || !IsInstanceValid(Player)) return;
|
|
|
|
var direction = (Player.GlobalPosition - collectable.GlobalPosition).Normalized();
|
|
var speed = direction.Length() / MagneticMoveDuration;
|
|
|
|
collectable.GlobalPosition += direction.Normalized() * speed;
|
|
}
|
|
|
|
public override void Initialize(Node owner, SkillData data, int level)
|
|
{
|
|
base.Initialize(owner, data, level);
|
|
|
|
if (Player == null)
|
|
{
|
|
GD.PushWarning("MagneticSkillComponent: Owner is not a Player/Node2D.");
|
|
}
|
|
|
|
if (MagneticArea == null)
|
|
{
|
|
if (owner is Area2D area2D) MagneticArea = area2D;
|
|
else
|
|
{
|
|
MagneticArea = owner.GetNodeOrNull<Area2D>("MagneticArea");
|
|
if (MagneticArea == null)
|
|
{
|
|
GD.PushError("MagneticSkillComponent: MagneticArea is not set.");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
ApplyCurrentUpgrade();
|
|
}
|
|
|
|
public override void Activate()
|
|
{
|
|
if (MagneticArea == null)
|
|
{
|
|
GD.PushError("MagneticSkillComponent: MagneticArea is not set.");
|
|
return;
|
|
}
|
|
|
|
MagneticArea.BodyEntered += OnBodyEntered;
|
|
MagneticArea.AreaEntered += OnAreaEntered;
|
|
}
|
|
|
|
public override void Deactivate()
|
|
{
|
|
if (MagneticArea == null) return;
|
|
|
|
MagneticArea.BodyEntered -= OnBodyEntered;
|
|
MagneticArea.AreaEntered -= OnAreaEntered;
|
|
}
|
|
|
|
public override void ApplyUpgrade(SkillUpgrade upgrade)
|
|
{
|
|
foreach (var property in upgrade.Properties)
|
|
{
|
|
Set(property.Key, property.Value);
|
|
}
|
|
}
|
|
} |