Line endings: LF everywhere

.gitattributes forces LF (CRLF only for .bat/.cmd), core.autocrlf is off;
files that differed only by CRLF are normalized.
This commit is contained in:
cthangover committed 2026-10-21 13:29:53 +02:00
1 parent a7d03cd41a
commit 7e78f60635
7 files changed
+302 -272

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
# Line endings: LF everywhere, on every OS, whatever core.autocrlf says.
* text=auto eol=lf
# cmd.exe misreads labels and goto in LF batch files, so they stay CRLF.
*.bat text eol=crlf
*.cmd text eol=crlf
# Binaries: never converted, never diffed as text.
*.png binary
*.jpg binary
*.jpeg binary
*.webp binary
*.svg text
*.ogg binary
*.wav binary
*.mp3 binary
*.ttf binary
*.otf binary
*.woff binary
*.woff2 binary
*.dll binary
*.so binary
*.dylib binary
*.pdb binary
*.exe binary
*.zip binary
*.pck binary
*.moc3 binary
*.res binary
*.scn binary
+37 -37
View File
@@ -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
+21 -21
View File
@@ -1,21 +1,21 @@
namespace Cthangover.Mods.Skills namespace Cthangover.Mods.Skills
{ {
/// <summary> /// <summary>
/// Represents the rarity tier of a skill card, determining its drop probability, /// Represents the rarity tier of a skill card, determining its drop probability,
/// visual frame treatment, and relative power budget. Higher tiers correspond to /// visual frame treatment, and relative power budget. Higher tiers correspond to
/// more potent effects and rarer acquisition chances. /// more potent effects and rarer acquisition chances.
/// </summary> /// </summary>
public enum RareType public enum RareType
{ {
/// <summary>Standard skill with the highest drop rate and baseline power.</summary> /// <summary>Standard skill with the highest drop rate and baseline power.</summary>
Common, Common,
/// <summary>Slightly improved stats and a lower drop rate than <c>Common</c>.</summary> /// <summary>Slightly improved stats and a lower drop rate than <c>Common</c>.</summary>
Uncommon, Uncommon,
/// <summary>Notably stronger, appearing infrequently in loot pools.</summary> /// <summary>Notably stronger, appearing infrequently in loot pools.</summary>
Rare, Rare,
/// <summary>Powerful skill with significant gameplay impact; very low drop chance.</summary> /// <summary>Powerful skill with significant gameplay impact; very low drop chance.</summary>
Epic, Epic,
/// <summary>The highest tier — game-changing abilities with extremely rare availability.</summary> /// <summary>The highest tier — game-changing abilities with extremely rare availability.</summary>
Legendary Legendary
} }
} }
+112 -112
View File
@@ -1,112 +1,112 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Cthangover.Core.Factories; using Cthangover.Core.Factories;
using Cthangover.Core.Utils; using Cthangover.Core.Utils;
using Godot; using Godot;
namespace Cthangover.Mods.Skills namespace Cthangover.Mods.Skills
{ {
/// <summary> /// <summary>
/// Immutable data model for a single skill definition, populated by /// Immutable data model for a single skill definition, populated by
/// <see cref="SkillFactory"/> from JSON assets. Each instance carries the /// <see cref="SkillFactory"/> from JSON assets. Each instance carries the
/// metadata required to render a skill card in the UI (<see cref="Sprite"/>, /// metadata required to render a skill card in the UI (<see cref="Sprite"/>,
/// <see cref="Name"/>, <see cref="Description"/>) and to resolve its gameplay /// <see cref="Name"/>, <see cref="Description"/>) and to resolve its gameplay
/// behaviour through <see cref="SkillType"/> and <see cref="RareType"/>. /// behaviour through <see cref="SkillType"/> and <see cref="RareType"/>.
/// Instances are shared across the runtime and should not be mutated after /// Instances are shared across the runtime and should not be mutated after
/// construction. /// construction.
/// </summary> /// </summary>
[Serializable] [Serializable]
[EntityKind("skill")] [EntityKind("skill")]
public class SkillInfo : IIdentifiable public class SkillInfo : IIdentifiable
{ {
/// <summary> /// <summary>
/// The unique string key of this skill, used as the primary lookup in /// The unique string key of this skill, used as the primary lookup in
/// <see cref="SkillFactory"/> and as the identity token in /// <see cref="SkillFactory"/> and as the identity token in
/// <see cref="SkillData.Skills"/>. /// <see cref="SkillData.Skills"/>.
/// </summary> /// </summary>
[JsonPropertyName("Id")] [JsonPropertyName("Id")]
public string ID { get; set; } public string ID { get; set; }
/// <summary> /// <summary>
/// The display name shown on the skill card. This value is passed through /// The display name shown on the skill card. This value is passed through
/// <see cref="TranslationServer.Translate"/> before rendering, allowing /// <see cref="TranslationServer.Translate"/> before rendering, allowing
/// localisation via Godot's translation system. /// localisation via Godot's translation system.
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary> /// <summary>
/// A longer textual description explaining what the skill does in gameplay /// A longer textual description explaining what the skill does in gameplay
/// terms. Displayed in tooltip and detail views alongside the card artwork. /// terms. Displayed in tooltip and detail views alongside the card artwork.
/// </summary> /// </summary>
public string Description { get; set; } public string Description { get; set; }
/// <summary> /// <summary>
/// The relative path to the skill's artwork texture, resolved inside the /// The relative path to the skill's artwork texture, resolved inside the
/// mod-group "characters/skills" by <see cref="TextureUtils.LoadFromModGroup"/> /// mod-group "characters/skills" by <see cref="TextureUtils.LoadFromModGroup"/>
/// when the <see cref="Sprite"/> property is first accessed. /// when the <see cref="Sprite"/> property is first accessed.
/// </summary> /// </summary>
public string Image { get; set; } public string Image { get; set; }
/// <summary> /// <summary>
/// Optional ID of the action card this skill gifts to the player when /// Optional ID of the action card this skill gifts to the player when
/// acquired (e.g. an active skill that hands over a battle card). /// acquired (e.g. an active skill that hands over a battle card).
/// Resolved against <see cref="Cthangover.Core.Factories.Impls.ActionCharacterFactory"/> /// Resolved against <see cref="Cthangover.Core.Factories.Impls.ActionCharacterFactory"/>
/// when the skills panel renders the detail view, and pushed into /// when the skills panel renders the detail view, and pushed into
/// <see cref="Cthangover.Core.Settings.ActionPoolData.ActionIds"/> by /// <see cref="Cthangover.Core.Settings.ActionPoolData.ActionIds"/> by
/// <see cref="SkillService"/> so the card becomes assignable to a /// <see cref="SkillService"/> so the card becomes assignable to a
/// character. Empty for skills that only act as passive gates and /// character. Empty for skills that only act as passive gates and
/// never produce a card. /// never produce a card.
/// </summary> /// </summary>
public string GrantsAction { get; set; } public string GrantsAction { get; set; }
/// <summary> /// <summary>
/// Numeric bonuses this skill grants while owned. They are the card's /// Numeric bonuses this skill grants while owned. They are the card's
/// actual payload: the skills panel shows the first effect on the grid /// actual payload: the skills panel shows the first effect on the grid
/// card, lists all of them in the study plate, and sums every owned /// card, lists all of them in the study plate, and sums every owned
/// skill's effects into the global "collection effect" plate via /// skill's effects into the global "collection effect" plate via
/// <see cref="SkillEffectAggregator"/>. Empty for skills that only gate /// <see cref="SkillEffectAggregator"/>. Empty for skills that only gate
/// content (e.g. unlock an action) without touching stats. /// content (e.g. unlock an action) without touching stats.
/// </summary> /// </summary>
[JsonPropertyName("Effects")] [JsonPropertyName("Effects")]
public List<SkillEffectInfo> Effects { get; set; } public List<SkillEffectInfo> Effects { get; set; }
/// <summary> /// <summary>
/// The gameplay classification of this skill (<c>Active</c>, <c>Passive</c>, /// The gameplay classification of this skill (<c>Active</c>, <c>Passive</c>,
/// or <c>ForCharacter</c>), serialised as a string in JSON and converted /// or <c>ForCharacter</c>), serialised as a string in JSON and converted
/// via <see cref="JsonStringEnumConverter"/>. /// via <see cref="JsonStringEnumConverter"/>.
/// </summary> /// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))] [JsonConverter(typeof(JsonStringEnumConverter))]
[JsonPropertyName("Type")] [JsonPropertyName("Type")]
public SkillType SkillType { get; set; } public SkillType SkillType { get; set; }
/// <summary> /// <summary>
/// The rarity tier of this skill, serialised as a string in JSON and /// The rarity tier of this skill, serialised as a string in JSON and
/// converted via <see cref="JsonStringEnumConverter"/>. Drives the colour /// converted via <see cref="JsonStringEnumConverter"/>. Drives the colour
/// of the card frame, study plate and rarity badge through /// of the card frame, study plate and rarity badge through
/// <see cref="SkillPalette"/>. /// <see cref="SkillPalette"/>.
/// </summary> /// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))] [JsonConverter(typeof(JsonStringEnumConverter))]
[JsonPropertyName("Rare")] [JsonPropertyName("Rare")]
public RareType RareType { get; set; } public RareType RareType { get; set; }
private Texture2D cacheSprite; private Texture2D cacheSprite;
/// <summary> /// <summary>
/// Lazily loads and caches the <see cref="Texture2D"/> for this skill's /// Lazily loads and caches the <see cref="Texture2D"/> for this skill's
/// card artwork. On first access the texture is resolved from the mod-group /// card artwork. On first access the texture is resolved from the mod-group
/// "characters/skills" using the <see cref="Image"/> path; subsequent /// "characters/skills" using the <see cref="Image"/> path; subsequent
/// accesses return the cached reference. /// accesses return the cached reference.
/// </summary> /// </summary>
public Texture2D Sprite public Texture2D Sprite
{ {
get get
{ {
if (cacheSprite == null) if (cacheSprite == null)
cacheSprite = TextureUtils.LoadFromModGroup("characters/skills", Image); cacheSprite = TextureUtils.LoadFromModGroup("characters/skills", Image);
return cacheSprite; return cacheSprite;
} }
} }
} }
} }
+38 -38
View File
@@ -1,38 +1,38 @@
namespace Cthangover.Mods.Skills namespace Cthangover.Mods.Skills
{ {
/// <summary> /// <summary>
/// Enumerates every skill available in the game by its canonical identifier. /// Enumerates every skill available in the game by its canonical identifier.
/// Each member corresponds to a JSON-definition entry loaded by /// Each member corresponds to a JSON-definition entry loaded by
/// <see cref="SkillFactory"/> and used to construct <see cref="SkillInfo"/> instances. /// <see cref="SkillFactory"/> and used to construct <see cref="SkillInfo"/> instances.
/// The underlying <c>int</c> values are not manually assigned; the enum serves /// The underlying <c>int</c> values are not manually assigned; the enum serves
/// purely as a compile-time-safe skill reference. /// purely as a compile-time-safe skill reference.
/// </summary> /// </summary>
public enum SkillName : int public enum SkillName : int
{ {
/// <summary> /// <summary>
/// A domination-type skill that allows the player to command enslaved units, /// A domination-type skill that allows the player to command enslaved units,
/// overriding enemy AI and redirecting attacks under the player's control. /// overriding enemy AI and redirecting attacks under the player's control.
/// </summary> /// </summary>
SLAVE_MASTER SLAVE_MASTER
} }
/// <summary> /// <summary>
/// Provides conversion helpers for <see cref="SkillName"/> values, used when /// Provides conversion helpers for <see cref="SkillName"/> values, used when
/// bridging the enum-based API with string-based lookups in /// bridging the enum-based API with string-based lookups in
/// <see cref="SkillData"/> and factory registries. /// <see cref="SkillData"/> and factory registries.
/// </summary> /// </summary>
public static class SkillNameExtensions public static class SkillNameExtensions
{ {
/// <summary> /// <summary>
/// Converts a <see cref="SkillName"/> enum value to its lowercase string /// Converts a <see cref="SkillName"/> enum value to its lowercase string
/// identifier, matching the format expected by <see cref="SkillData.Skills"/> /// identifier, matching the format expected by <see cref="SkillData.Skills"/>
/// and serialization layers. /// and serialization layers.
/// </summary> /// </summary>
/// <param name="skill">The skill enum value to convert.</param> /// <param name="skill">The skill enum value to convert.</param>
/// <returns>The lowercase name of the enum constant (e.g. "slave_master").</returns> /// <returns>The lowercase name of the enum constant (e.g. "slave_master").</returns>
public static string ID(this SkillName skill) public static string ID(this SkillName skill)
{ {
return skill.ToString().ToLower(); return skill.ToString().ToLower();
} }
} }
} }
+26 -26
View File
@@ -1,26 +1,26 @@
namespace Cthangover.Mods.Skills namespace Cthangover.Mods.Skills
{ {
/// <summary> /// <summary>
/// Classifies how a skill behaves during gameplay. This distinction drives /// Classifies how a skill behaves during gameplay. This distinction drives
/// which battle-phase the skill can be used in and how its effects are resolved /// which battle-phase the skill can be used in and how its effects are resolved
/// by the combat engine. /// by the combat engine.
/// </summary> /// </summary>
public enum SkillType public enum SkillType
{ {
/// <summary> /// <summary>
/// Must be intentionally triggered during the player's turn, consuming an action /// Must be intentionally triggered during the player's turn, consuming an action
/// resource and targeting a specific ally or enemy. /// resource and targeting a specific ally or enemy.
/// </summary> /// </summary>
Active, Active,
/// <summary> /// <summary>
/// Remains in effect continuously once acquired, providing a persistent buff /// Remains in effect continuously once acquired, providing a persistent buff
/// or aura without requiring any player input. /// or aura without requiring any player input.
/// </summary> /// </summary>
Passive, Passive,
/// <summary> /// <summary>
/// Applies directly to the owning character as a stat modifier or intrinsic trait, /// Applies directly to the owning character as a stat modifier or intrinsic trait,
/// rather than being a card the player selects each turn. /// rather than being a card the player selects each turn.
/// </summary> /// </summary>
ForCharacter, ForCharacter,
} }
} }
+38 -38
View File
@@ -1,38 +1,38 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Cthangover.Core.Factories.Impls; using Cthangover.Core.Factories.Impls;
using Cthangover.Core.Settings; using Cthangover.Core.Settings;
using Cthangover.Mods.Interface.Base.Lists.Impls; using Cthangover.Mods.Interface.Base.Lists.Impls;
namespace Cthangover.Mods.Skills namespace Cthangover.Mods.Skills
{ {
/// <summary> /// <summary>
/// UI widget that displays all skills currently owned by the player in a /// UI widget that displays all skills currently owned by the player in a
/// column-based card grid. Extends /// column-based card grid. Extends
/// <see cref="ColumnCellListWidget{TItem, TModel}"/> to reuse the generic /// <see cref="ColumnCellListWidget{TItem, TModel}"/> to reuse the generic
/// list-rendering pipeline. When the widget is populated it reads the set /// list-rendering pipeline. When the widget is populated it reads the set
/// of owned skill IDs from <see cref="SkillData.Skills"/> in the current /// of owned skill IDs from <see cref="SkillData.Skills"/> in the current
/// <see cref="GameData"/> runtime, resolves each ID to a /// <see cref="GameData"/> runtime, resolves each ID to a
/// <see cref="SkillInfo"/> via <see cref="SkillFactory.Instance"/>, and /// <see cref="SkillInfo"/> via <see cref="SkillFactory.Instance"/>, and
/// hands the resulting models to the list for rendering as /// hands the resulting models to the list for rendering as
/// <see cref="SkillCardBehaviour"/> items. /// <see cref="SkillCardBehaviour"/> items.
/// </summary> /// </summary>
public partial class SkillWidget : ColumnCellListWidget<SkillCardBehaviour, SkillInfo> public partial class SkillWidget : ColumnCellListWidget<SkillCardBehaviour, SkillInfo>
{ {
/// <summary> /// <summary>
/// Produces the collection of <see cref="SkillInfo"/> models that the /// Produces the collection of <see cref="SkillInfo"/> models that the
/// list widget will render. Each ownedskill ID from /// list widget will render. Each ownedskill ID from
/// <see cref="GameData.Instance.Runtime.SkillData"/> is resolved through /// <see cref="GameData.Instance.Runtime.SkillData"/> is resolved through
/// <see cref="SkillFactory.Instance.Get"/> and collected into a /// <see cref="SkillFactory.Instance.Get"/> and collected into a
/// <see cref="List{T}"/>. /// <see cref="List{T}"/>.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// A snapshot of all currently owned skills, each as a fully-populated /// A snapshot of all currently owned skills, each as a fully-populated
/// <see cref="SkillInfo"/> instance. /// <see cref="SkillInfo"/> instance.
/// </returns> /// </returns>
public override ICollection<SkillInfo> CreateModels() public override ICollection<SkillInfo> CreateModels()
{ {
return GameData.Instance.Runtime.SkillData.Skills.Select(x => SkillFactory.Instance.Get(x)).ToList(); return GameData.Instance.Runtime.SkillData.Skills.Select(x => SkillFactory.Instance.Get(x)).ToList();
} }
} }
} }