Commit pending working-tree changes (local edits, line endings)
This commit is contained in:
1 parent
a9ed1b09c0
commit
f4dc0c0b04
5 files changed
+215
-215
No files matched your search
+37
-37
@@ -1,37 +1,37 @@
|
|||||||
# Godot 4.x
|
# Godot 4.x
|
||||||
.godot/
|
.godot/
|
||||||
.idea/
|
.idea/
|
||||||
sdk/
|
sdk/
|
||||||
bin/
|
bin/
|
||||||
obj/
|
obj/
|
||||||
|
|
||||||
#ai
|
#ai
|
||||||
.omo/
|
.omo/
|
||||||
.opencode/
|
.opencode/
|
||||||
|
|
||||||
gen/
|
gen/
|
||||||
obj/
|
obj/
|
||||||
bin/
|
bin/
|
||||||
|
|
||||||
*.tres~
|
*.tres~
|
||||||
*.tscn~
|
*.tscn~
|
||||||
|
|
||||||
# GDScript LSP
|
# GDScript LSP
|
||||||
.godot/
|
.godot/
|
||||||
|
|
||||||
# Export
|
# Export
|
||||||
*.exe
|
*.exe
|
||||||
*.dmg
|
*.dmg
|
||||||
*.apk
|
*.apk
|
||||||
*.aab
|
*.aab
|
||||||
*.pck
|
*.pck
|
||||||
*.zip
|
*.zip
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
*.import
|
*.import
|
||||||
*.godot.uid
|
*.godot.uid
|
||||||
+48
-48
@@ -1,48 +1,48 @@
|
|||||||
using Cthangover.Core.Settings;
|
using Cthangover.Core.Settings;
|
||||||
|
|
||||||
namespace Cthangover.Core.Relationship
|
namespace Cthangover.Core.Relationship
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Per-recruit behaviour plugin discovered via reflection from mod
|
/// Per-recruit behaviour plugin discovered via reflection from mod
|
||||||
/// assemblies. Each implementation is registered into
|
/// assemblies. Each implementation is registered into
|
||||||
/// <see cref="RecruitBehaviourRegistry"/> by
|
/// <see cref="RecruitBehaviourRegistry"/> by
|
||||||
/// <see cref="Mods.ModAssemblyLoader.RegisterAssembly"/> and then
|
/// <see cref="Mods.ModAssemblyLoader.RegisterAssembly"/> and then
|
||||||
/// invoked for <b>every</b> active recruit — not just those from the
|
/// invoked for <b>every</b> active recruit — not just those from the
|
||||||
/// owning mod — during tick, configure, and removal lifecycle events.
|
/// owning mod — during tick, configure, and removal lifecycle events.
|
||||||
///
|
///
|
||||||
/// This cross-recruit dispatch pattern is intentional: a behaviour
|
/// This cross-recruit dispatch pattern is intentional: a behaviour
|
||||||
/// might want to introspect all recruits (e.g. a "rivalry" system
|
/// might want to introspect all recruits (e.g. a "rivalry" system
|
||||||
/// that checks for conflicting personalities), so the registry passes
|
/// that checks for conflicting personalities), so the registry passes
|
||||||
/// the full recruit list to every behaviour rather than filtering by
|
/// the full recruit list to every behaviour rather than filtering by
|
||||||
/// ownership.
|
/// ownership.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRecruitBehaviour
|
public interface IRecruitBehaviour
|
||||||
{
|
{
|
||||||
/// <summary>Unique identifier for lookup via <c>RecruitBehaviourRegistry.Get</c>.</summary>
|
/// <summary>Unique identifier for lookup via <c>RecruitBehaviourRegistry.Get</c>.</summary>
|
||||||
string Id { get; }
|
string Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called once when a recruit is added to the party
|
/// Called once when a recruit is added to the party
|
||||||
/// (via <c>RecruitingData.Add</c>). Use for initial stat
|
/// (via <c>RecruitingData.Add</c>). Use for initial stat
|
||||||
/// setup, buff application, or spawning companion nodes.
|
/// setup, buff application, or spawning companion nodes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void ConfigureRecruit(Recruit recruit, RuntimeData runtime);
|
void ConfigureRecruit(Recruit recruit, RuntimeData runtime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called every game tick for each active recruit. The
|
/// Called every game tick for each active recruit. The
|
||||||
/// <paramref name="currentTick"/> value is the global
|
/// <paramref name="currentTick"/> value is the global
|
||||||
/// <c>RuntimeData.Time.Tick</c> counter — use it for
|
/// <c>RuntimeData.Time.Tick</c> counter — use it for
|
||||||
/// cooldown-based or periodic logic rather than maintaining
|
/// cooldown-based or periodic logic rather than maintaining
|
||||||
/// a private timer.
|
/// a private timer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void OnTick(Recruit recruit, RuntimeData runtime, long currentTick);
|
void OnTick(Recruit recruit, RuntimeData runtime, long currentTick);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a recruit is removed from the party
|
/// Called when a recruit is removed from the party
|
||||||
/// (via <c>RecruitingData.Remove</c>). Clean up any
|
/// (via <c>RecruitingData.Remove</c>). Clean up any
|
||||||
/// persisted state, buffs, or companion nodes.
|
/// persisted state, buffs, or companion nodes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void OnRemove(Recruit recruit, RuntimeData runtime);
|
void OnRemove(Recruit recruit, RuntimeData runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+33
-33
@@ -1,33 +1,33 @@
|
|||||||
using Cthangover.Core.Characters;
|
using Cthangover.Core.Characters;
|
||||||
using Cthangover.Core.Settings;
|
using Cthangover.Core.Settings;
|
||||||
|
|
||||||
namespace Cthangover.Core.Relationship
|
namespace Cthangover.Core.Relationship
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gating predicate for the recruit system. Implementations are
|
/// Gating predicate for the recruit system. Implementations are
|
||||||
/// auto-discovered from mod assemblies by
|
/// auto-discovered from mod assemblies by
|
||||||
/// <see cref="RecruitBehaviourRegistry.RegisterAssembly"/> and
|
/// <see cref="RecruitBehaviourRegistry.RegisterAssembly"/> and
|
||||||
/// evaluated conjunctively — <b>all</b> conditions must return
|
/// evaluated conjunctively — <b>all</b> conditions must return
|
||||||
/// <c>true</c> for recruitment to succeed.
|
/// <c>true</c> for recruitment to succeed.
|
||||||
///
|
///
|
||||||
/// Conditions receive the full <see cref="Character"/> and
|
/// Conditions receive the full <see cref="Character"/> and
|
||||||
/// <see cref="RuntimeData"/> so they can inspect character stats,
|
/// <see cref="RuntimeData"/> so they can inspect character stats,
|
||||||
/// inventory, relationship flags, quest state, or any other
|
/// inventory, relationship flags, quest state, or any other
|
||||||
/// runtime-accessible data when deciding whether a given enemy is
|
/// runtime-accessible data when deciding whether a given enemy is
|
||||||
/// recruitable.
|
/// recruitable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRecruitCondition
|
public interface IRecruitCondition
|
||||||
{
|
{
|
||||||
/// <summary>Unique identifier for debugging and override lookups.</summary>
|
/// <summary>Unique identifier for debugging and override lookups.</summary>
|
||||||
string Id { get; }
|
string Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns <c>true</c> if the given <paramref name="enemy"/>
|
/// Returns <c>true</c> if the given <paramref name="enemy"/>
|
||||||
/// can be recruited under current game state. Called from
|
/// can be recruited under current game state. Called from
|
||||||
/// <c>RecruitBehaviourRegistry.CanRecruit</c> as part of a
|
/// <c>RecruitBehaviourRegistry.CanRecruit</c> as part of a
|
||||||
/// conjunctive gate — a single <c>false</c> blocks recruitment.
|
/// conjunctive gate — a single <c>false</c> blocks recruitment.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool CanRecruit(Character enemy, RuntimeData runtime);
|
bool CanRecruit(Character enemy, RuntimeData runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+35
-35
@@ -1,35 +1,35 @@
|
|||||||
using System;
|
using System;
|
||||||
using Cthangover.Core.Utils;
|
using Cthangover.Core.Utils;
|
||||||
|
|
||||||
namespace Cthangover.Core.Relationship
|
namespace Cthangover.Core.Relationship
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runtime model for a recruited party member. Stores the recruit's
|
/// Runtime model for a recruited party member. Stores the recruit's
|
||||||
/// unique ID, the character template it was created from, and a
|
/// unique ID, the character template it was created from, and a
|
||||||
/// modifiable <see cref="Utility.PropertyData"/> bag that behaviours
|
/// modifiable <see cref="Utility.PropertyData"/> bag that behaviours
|
||||||
/// read and mutate during tick/configure events.
|
/// read and mutate during tick/configure events.
|
||||||
///
|
///
|
||||||
/// Marked <c>[Serializable]</c> so the recruiting roster survives
|
/// Marked <c>[Serializable]</c> so the recruiting roster survives
|
||||||
/// save/load — <c>PropertyData</c> serialises its nested values
|
/// save/load — <c>PropertyData</c> serialises its nested values
|
||||||
/// automatically. The <c>PROP_HEALTH</c> constant is the conventional
|
/// automatically. The <c>PROP_HEALTH</c> constant is the conventional
|
||||||
/// key for health tracking; behaviours that need custom state
|
/// key for health tracking; behaviours that need custom state
|
||||||
/// (e.g. morale, loyalty timers) add their own keys to the
|
/// (e.g. morale, loyalty timers) add their own keys to the
|
||||||
/// <c>Properties</c> bag at configure time.
|
/// <c>Properties</c> bag at configure time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Recruit
|
public class Recruit
|
||||||
{
|
{
|
||||||
/// <summary>Conventional key for the recruit's health value in the <c>Properties</c> bag.</summary>
|
/// <summary>Conventional key for the recruit's health value in the <c>Properties</c> bag.</summary>
|
||||||
public const string PROP_HEALTH = "Health";
|
public const string PROP_HEALTH = "Health";
|
||||||
|
|
||||||
/// <summary>Unique instance ID (auto-generated via <c>RecruitingData.GenID</c>).</summary>
|
/// <summary>Unique instance ID (auto-generated via <c>RecruitingData.GenID</c>).</summary>
|
||||||
public string ID { get; set; }
|
public string ID { get; set; }
|
||||||
|
|
||||||
/// <summary>Character template ID this recruit was spawned from.</summary>
|
/// <summary>Character template ID this recruit was spawned from.</summary>
|
||||||
public string CharacterID { get; set; }
|
public string CharacterID { get; set; }
|
||||||
|
|
||||||
/// <summary>Mutable property bag — behaviours read/write custom state here.</summary>
|
/// <summary>Mutable property bag — behaviours read/write custom state here.</summary>
|
||||||
public PropertyData Properties { get; set; } = new();
|
public PropertyData Properties { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,62 +1,62 @@
|
|||||||
using Cthangover.Core.Scenes;
|
using Cthangover.Core.Scenes;
|
||||||
using Cthangover.Core.UI.Event;
|
using Cthangover.Core.UI.Event;
|
||||||
|
|
||||||
namespace Cthangover.Core.Relationship
|
namespace Cthangover.Core.Relationship
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lazy bridge between the scene timer system and the recruit
|
/// Lazy bridge between the scene timer system and the recruit
|
||||||
/// behaviour tick loop. Implements <see cref="IOnTimeEvent"/>
|
/// behaviour tick loop. Implements <see cref="IOnTimeEvent"/>
|
||||||
/// so it can be registered with <see cref="SceneEventController"/>
|
/// so it can be registered with <see cref="SceneEventController"/>
|
||||||
/// via <c>AddTimerTickEventListener</c>.
|
/// via <c>AddTimerTickEventListener</c>.
|
||||||
///
|
///
|
||||||
/// Registration is lazy (<see cref="EnsureRegistered"/> is a no-op
|
/// Registration is lazy (<see cref="EnsureRegistered"/> is a no-op
|
||||||
/// after the first call) because the recruit system should not
|
/// after the first call) because the recruit system should not
|
||||||
/// force the timer subsystem to activate if no behaviours are
|
/// force the timer subsystem to activate if no behaviours are
|
||||||
/// actually loaded. The first behaviour lifecycle method in
|
/// actually loaded. The first behaviour lifecycle method in
|
||||||
/// <see cref="RecruitBehaviourRegistry"/> calls
|
/// <see cref="RecruitBehaviourRegistry"/> calls
|
||||||
/// <c>EnsureRegistered</c>, which finds the scene's
|
/// <c>EnsureRegistered</c>, which finds the scene's
|
||||||
/// <c>EventController</c> node and subscribes.
|
/// <c>EventController</c> node and subscribes.
|
||||||
///
|
///
|
||||||
/// <c>Priority = 0</c> so recruit ticks fire at a neutral point in
|
/// <c>Priority = 0</c> so recruit ticks fire at a neutral point in
|
||||||
/// the timer event chain — before or after other listeners as
|
/// the timer event chain — before or after other listeners as
|
||||||
/// determined by their relative priorities.
|
/// determined by their relative priorities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RecruitTickController : IOnTimeEvent
|
public class RecruitTickController : IOnTimeEvent
|
||||||
{
|
{
|
||||||
/// <summary>Neutral priority — doesn't preempt or follow any specific listener.</summary>
|
/// <summary>Neutral priority — doesn't preempt or follow any specific listener.</summary>
|
||||||
public int Priority => 0;
|
public int Priority => 0;
|
||||||
|
|
||||||
private bool _registered;
|
private bool _registered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the scene's <c>EventController</c> node and subscribes
|
/// Finds the scene's <c>EventController</c> node and subscribes
|
||||||
/// this controller as a timer-tick listener. Idempotent —
|
/// this controller as a timer-tick listener. Idempotent —
|
||||||
/// subsequent calls do nothing.
|
/// subsequent calls do nothing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void EnsureRegistered()
|
public void EnsureRegistered()
|
||||||
{
|
{
|
||||||
if (_registered)
|
if (_registered)
|
||||||
return;
|
return;
|
||||||
var eventController = SceneContextNode.FindNode<SceneEventController>("EventController");
|
var eventController = SceneContextNode.FindNode<SceneEventController>("EventController");
|
||||||
if (eventController == null)
|
if (eventController == null)
|
||||||
return;
|
return;
|
||||||
eventController.AddTimerTickEventListener(this);
|
eventController.AddTimerTickEventListener(this);
|
||||||
_registered = true;
|
_registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called by <see cref="SceneEventController"/> on every
|
/// Called by <see cref="SceneEventController"/> on every
|
||||||
/// timer tick. Delegates to
|
/// timer tick. Delegates to
|
||||||
/// <see cref="RecruitBehaviourRegistry.OnTick"/>.
|
/// <see cref="RecruitBehaviourRegistry.OnTick"/>.
|
||||||
/// Ticks also fire during the launcher boot window, so the registry
|
/// Ticks also fire during the launcher boot window, so the registry
|
||||||
/// side must not touch <c>GameData.Instance.Runtime</c> or mod data
|
/// side must not touch <c>GameData.Instance.Runtime</c> or mod data
|
||||||
/// until <c>Boot.ModsReady</c> (see the boot-window contract on
|
/// until <c>Boot.ModsReady</c> (see the boot-window contract on
|
||||||
/// <c>IOnTimeEvent</c>; core-side reference: TimeTickController).
|
/// <c>IOnTimeEvent</c>; core-side reference: TimeTickController).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OnTimerTick()
|
public void OnTimerTick()
|
||||||
{
|
{
|
||||||
RecruitBehaviourRegistry.Instance.OnTick();
|
RecruitBehaviourRegistry.Instance.OnTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user