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:43 +02:00
1 parent 6bb47971a3
commit d560638501
5 files changed
+221 -191

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
+63 -63
View File
@@ -1,63 +1,63 @@
using System.Collections.Generic; using System.Collections.Generic;
using Cthangover.Core.Items; using Cthangover.Core.Items;
namespace Cthangover.Core.Factories.Impls namespace Cthangover.Core.Factories.Impls
{ {
/// <summary> /// <summary>
/// Registry of item action behaviours, indexed by <c>ID</c>. It discovers /// Registry of item action behaviours, indexed by <c>ID</c>. It discovers
/// nothing itself: C# actions of every mod arrive through /// nothing itself: C# actions of every mod arrive through
/// <c>ItemActionConsumer</c> as the kernel registers their assembly and /// <c>ItemActionConsumer</c> as the kernel registers their assembly and
/// leave with their mod, and GDScript-declared actions arrive through /// leave with their mod, and GDScript-declared actions arrive through
/// <c>ItemActionBridge</c>. A mod therefore introduces a new item action /// <c>ItemActionBridge</c>. A mod therefore introduces a new item action
/// simply by containing a public class that implements the interface. /// simply by containing a public class that implements the interface.
/// ///
/// The <c>"null"</c> ID string is treated as a no-op action (the /// The <c>"null"</c> ID string is treated as a no-op action (the
/// fallback for items that don't have an on-use effect), avoiding /// fallback for items that don't have an on-use effect), avoiding
/// the need for a sentinel <c>NullItemAction</c> class. /// the need for a sentinel <c>NullItemAction</c> class.
/// <para/> /// <para/>
/// The single instance lives in this mod assembly as a static lazy /// The single instance lives in this mod assembly as a static lazy
/// singleton; the static facade stays as the public API. /// singleton; the static facade stays as the public API.
/// </summary> /// </summary>
public class ItemActionFactory public class ItemActionFactory
{ {
private static ItemActionFactory _instance; private static ItemActionFactory _instance;
/// <summary>Static lazy singleton; kept as the public API.</summary> /// <summary>Static lazy singleton; kept as the public API.</summary>
public static ItemActionFactory Instance => _instance ??= new ItemActionFactory(); public static ItemActionFactory Instance => _instance ??= new ItemActionFactory();
private readonly IDictionary<string, IItemAction> data = new Dictionary<string, IItemAction>(); private readonly IDictionary<string, IItemAction> data = new Dictionary<string, IItemAction>();
internal ItemActionFactory() internal ItemActionFactory()
{ {
} }
/// <summary>Registers a single action under its <see cref="IItemAction.ID"/>; the first action of an id wins, null/empty ids are ignored.</summary> /// <summary>Registers a single action under its <see cref="IItemAction.ID"/>; the first action of an id wins, null/empty ids are ignored.</summary>
public void Register(IItemAction action) public void Register(IItemAction action)
{ {
if (action != null && !string.IsNullOrEmpty(action.ID) && !data.ContainsKey(action.ID)) if (action != null && !string.IsNullOrEmpty(action.ID) && !data.ContainsKey(action.ID))
data[action.ID] = action; data[action.ID] = action;
} }
/// <summary> /// <summary>
/// Removes exactly <paramref name="action"/> (its mod is being unloaded); /// Removes exactly <paramref name="action"/> (its mod is being unloaded);
/// an id owned by another action instance is left alone. /// an id owned by another action instance is left alone.
/// </summary> /// </summary>
public void Unregister(IItemAction action) public void Unregister(IItemAction action)
{ {
if (action != null && !string.IsNullOrEmpty(action.ID) && data.TryGetValue(action.ID, out var registered) && registered == action) if (action != null && !string.IsNullOrEmpty(action.ID) && data.TryGetValue(action.ID, out var registered) && registered == action)
data.Remove(action.ID); data.Remove(action.ID);
} }
/// <summary> /// <summary>
/// Resolves the behaviour registered under <paramref name="id"/>. /// Resolves the behaviour registered under <paramref name="id"/>.
/// The special id <c>"null"</c> (or an empty value) is an explicit /// The special id <c>"null"</c> (or an empty value) is an explicit
/// no-action marker and returns <c>null</c>, as does an unknown id. /// no-action marker and returns <c>null</c>, as does an unknown id.
/// </summary> /// </summary>
public IItemAction Get(string id) public IItemAction Get(string id)
{ {
if (string.IsNullOrWhiteSpace(id) || id == "null") if (string.IsNullOrWhiteSpace(id) || id == "null")
return null; return null;
return data[id]; return data[id];
} }
} }
} }
+50 -50
View File
@@ -1,50 +1,50 @@
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.Items; using Cthangover.Core.Items;
namespace Cthangover.Core.Settings namespace Cthangover.Core.Settings
{ {
/// <summary> /// <summary>
/// Tracks which crafting recipes the player has unlocked. Internally /// Tracks which crafting recipes the player has unlocked. Internally
/// a <see cref="HashSet{String}"/> of recipe IDs that provides <c>O(1)</c> /// a <see cref="HashSet{String}"/> of recipe IDs that provides <c>O(1)</c>
/// lookup. Recipes can be queried by <see cref="IRecipe.WorkbenchType"/> /// lookup. Recipes can be queried by <see cref="IRecipe.WorkbenchType"/>
/// via <see cref="GetRecipesByType"/>, which resolves each ID through /// via <see cref="GetRecipesByType"/>, which resolves each ID through
/// <see cref="Cthangover.Core.Factories.Impls.RecipeFactory"/> and /// <see cref="Cthangover.Core.Factories.Impls.RecipeFactory"/> and
/// filters the resulting <see cref="IRecipe"/> objects. /// filters the resulting <see cref="IRecipe"/> objects.
/// </summary> /// </summary>
public class RecipeData : IRecipeData public class RecipeData : IRecipeData
{ {
/// <summary>Set of known recipe IDs (duplicate insertion is silently ignored).</summary> /// <summary>Set of known recipe IDs (duplicate insertion is silently ignored).</summary>
public HashSet<string> Data { get; set; } = new(); public HashSet<string> Data { get; set; } = new();
/// <summary> /// <summary>
/// Unlocks a recipe by ID. Returns <c>false</c> if the recipe /// Unlocks a recipe by ID. Returns <c>false</c> if the recipe
/// was already known (duplicate). /// was already known (duplicate).
/// </summary> /// </summary>
public bool Add(string id) public bool Add(string id)
{ {
return Data.Add(id); return Data.Add(id);
} }
/// <summary><c>true</c> if the recipe with the given ID is already unlocked.</summary> /// <summary><c>true</c> if the recipe with the given ID is already unlocked.</summary>
public bool Has(string id) public bool Has(string id)
{ {
return Data.Contains(id); return Data.Contains(id);
} }
/// <summary> /// <summary>
/// Returns all known recipes that belong to the specified /// Returns all known recipes that belong to the specified
/// <see cref="WorkbenchType"/>. Each ID is resolved via /// <see cref="WorkbenchType"/>. Each ID is resolved via
/// <see cref="Cthangover.Core.Factories.Impls.RecipeFactory.Instance"/> /// <see cref="Cthangover.Core.Factories.Impls.RecipeFactory.Instance"/>
/// and filtered; IDs that resolve to <c>null</c> are silently /// and filtered; IDs that resolve to <c>null</c> are silently
/// dropped. /// dropped.
/// </summary> /// </summary>
public List<IRecipe> GetRecipesByType(WorkbenchType type) public List<IRecipe> GetRecipesByType(WorkbenchType type)
{ {
return Data.Select(o => RecipeFactory.Instance.Get(o)) return Data.Select(o => RecipeFactory.Instance.Get(o))
.Where(o => o.WorkbenchType == type) .Where(o => o.WorkbenchType == type)
.ToList(); .ToList();
} }
} }
} }
+41 -41
View File
@@ -1,41 +1,41 @@
using System.Collections.Generic; using System.Collections.Generic;
using Cthangover.Core.Items; using Cthangover.Core.Items;
using Cthangover.Mods.Interface.Base.Lists.Impls; using Cthangover.Mods.Interface.Base.Lists.Impls;
namespace Cthangover.Core.UI.Inventory namespace Cthangover.Core.UI.Inventory
{ {
/// <summary> /// <summary>
/// Grid-based inventory display using ColumnCellListWidget. Binds an /// Grid-based inventory display using ColumnCellListWidget. Binds an
/// external List&lt;IItemContainer&gt;. The List property setter auto-refreshes /// external List&lt;IItemContainer&gt;. The List property setter auto-refreshes
/// the UI — intended for data-driven updates where the inventory source /// the UI — intended for data-driven updates where the inventory source
/// pushes a new list reference rather than items mutating in place. /// pushes a new list reference rather than items mutating in place.
/// </summary> /// </summary>
public partial class InventoryBagBehaviour : ColumnCellListWidget<InventoryItemBehaviour, IItemContainer> public partial class InventoryBagBehaviour : ColumnCellListWidget<InventoryItemBehaviour, IItemContainer>
{ {
private List<IItemContainer> list; private List<IItemContainer> list;
/// <summary> /// <summary>
/// Bound inventory data source. Setting this property immediately rebuilds /// Bound inventory data source. Setting this property immediately rebuilds
/// the grid display via <see cref="Refresh"/>. The entire grid is /// the grid display via <see cref="Refresh"/>. The entire grid is
/// reconstructed from the new list reference. /// reconstructed from the new list reference.
/// </summary> /// </summary>
public List<IItemContainer> List public List<IItemContainer> List
{ {
get => list; get => list;
set set
{ {
list = value; list = value;
Refresh(); Refresh();
} }
} }
/// <summary> /// <summary>
/// Provides the current <see cref="List"/> as the data collection for the /// Provides the current <see cref="List"/> as the data collection for the
/// <see cref="ColumnCellListWidget{TItem, TModel}"/> base. /// <see cref="ColumnCellListWidget{TItem, TModel}"/> base.
/// </summary> /// </summary>
public override ICollection<IItemContainer> CreateModels() public override ICollection<IItemContainer> CreateModels()
{ {
return list; return list;
} }
} }
} }