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:32 +02:00
1 parent 422802b12e
commit ad3ab315ea
11 files changed
+347 -317

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/
.idea/
sdk/
bin/
obj/
#ai
.omo/
.opencode/
gen/
obj/
bin/
*.tres~
*.tscn~
# GDScript LSP
.godot/
# Export
*.exe
*.dmg
*.apk
*.aab
*.pck
*.zip
*.log
# OS
.DS_Store
Thumbs.db
# Editor
*.import
*.godot.uid
# Godot 4.x
.godot/
.idea/
sdk/
bin/
obj/
#ai
.omo/
.opencode/
gen/
obj/
bin/
*.tres~
*.tscn~
# GDScript LSP
.godot/
# Export
*.exe
*.dmg
*.apk
*.aab
*.pck
*.zip
*.log
# OS
.DS_Store
Thumbs.db
# Editor
*.import
*.godot.uid
+13 -13
View File
@@ -1,14 +1,14 @@
{
"Kind": "item",
"Items": [
{
"Id": "recipe/wolf_meat_to_ration",
"Name": "items/recipe/wolf_meat_to_ration/name",
"Description": "items/recipe/wolf_meat_to_ration/desc",
"Cost": 1,
"Sprite": "recipe/cooking_recipe",
"ItemType": "Recipe,Used",
"ItemAction": "action/recipe/wolf_meat_to_ration"
}
]
{
"Kind": "item",
"Items": [
{
"Id": "recipe/wolf_meat_to_ration",
"Name": "items/recipe/wolf_meat_to_ration/name",
"Description": "items/recipe/wolf_meat_to_ration/desc",
"Cost": 1,
"Sprite": "recipe/cooking_recipe",
"ItemType": "Recipe,Used",
"ItemAction": "action/recipe/wolf_meat_to_ration"
}
]
}
+22 -22
View File
@@ -1,22 +1,22 @@
mod_cooking_name = Cooking
mod_cooking_desc = Cooking mechanic: the kitchen workbench in home_kitchen with recipe-based cooking (e.g. wolf meat into rations), a ration statistics panel and the cooking scenario.
ui/cook/cook = Cook
ui/cook/close = Close
ui/cook/title = Food preparation
ui/cook/recipe_time = {0} minutes
ui/cook/recipe_out = Cooking result: {0}
ui/diner/rationcount = Rations: {0}
ui/diner/rationday = Daily consumption: {0}
ui/diner/rationmax = Supplies will last {0} days
items/food/ration/name = Ration
items/food/ration/desc = A daily ration unit for one person
items/food/wolf_meat/name = Wolf cutlet
items/food/wolf_meat/desc = Raw wolf meat
items/resource/branches/name = Branches
items/resource/branches/desc = Fuel for a campfire
recipe/wolf_meat_to_ration/name = Ration from wolf meat
recipe/wolf_meat_to_ration/desc = A recipe describing how to properly cook wolf meat to make it safe to eat
items/recipe/wolf_meat_to_ration/name = Recipe: ration from wolf meat
items/recipe/wolf_meat_to_ration/desc = Teaches how to cook wolf meat into rations that are safe to eat
mod_cooking/rations_per_character = Rations per person per day
mod_cooking_name = Cooking
mod_cooking_desc = Cooking mechanic: the kitchen workbench in home_kitchen with recipe-based cooking (e.g. wolf meat into rations), a ration statistics panel and the cooking scenario.
ui/cook/cook = Cook
ui/cook/close = Close
ui/cook/title = Food preparation
ui/cook/recipe_time = {0} minutes
ui/cook/recipe_out = Cooking result: {0}
ui/diner/rationcount = Rations: {0}
ui/diner/rationday = Daily consumption: {0}
ui/diner/rationmax = Supplies will last {0} days
items/food/ration/name = Ration
items/food/ration/desc = A daily ration unit for one person
items/food/wolf_meat/name = Wolf cutlet
items/food/wolf_meat/desc = Raw wolf meat
items/resource/branches/name = Branches
items/resource/branches/desc = Fuel for a campfire
recipe/wolf_meat_to_ration/name = Ration from wolf meat
recipe/wolf_meat_to_ration/desc = A recipe describing how to properly cook wolf meat to make it safe to eat
items/recipe/wolf_meat_to_ration/name = Recipe: ration from wolf meat
items/recipe/wolf_meat_to_ration/desc = Teaches how to cook wolf meat into rations that are safe to eat
mod_cooking/rations_per_character = Rations per person per day
+22 -22
View File
@@ -1,22 +1,22 @@
mod_cooking_name = Готовка
mod_cooking_desc = Механика готовки: верстак на кухне home_kitchen с рецептами (например, волчье мясо в рационы), панель статистики рационов и сценар готовки.
ui/cook/cook = Готовить
ui/cook/close = Выйти
ui/cook/title = Приготовление еды
ui/cook/recipe_time = {0} минут
ui/cook/recipe_out = Результат приготовления: {0}
ui/diner/rationcount = Пайков: {0}
ui/diner/rationday = Потребление в сутки: {0}
ui/diner/rationmax = Запасов хватит на {0} дней
items/food/ration/name = Рацион
items/food/ration/desc = Единица суточного рациона для одного человека
items/food/wolf_meat/name = Волчья вырезка
items/food/wolf_meat/desc = Сырое мясо волка
items/resource/branches/name = Ветки
items/resource/branches/desc = Топливо для костра
recipe/wolf_meat_to_ration/name = Рацион из волчьего мяса
recipe/wolf_meat_to_ration/desc = Рецепт описывает как правильно приготовить волчатину, чтобы безопасно употребить её в пищу
items/recipe/wolf_meat_to_ration/name = Рецепт: рацион из волчьего мяса
items/recipe/wolf_meat_to_ration/desc = Учит готовить из волчатины рационы, которые безопасно есть
mod_cooking/rations_per_character = Рационов на персонажа в сутки
mod_cooking_name = Готовка
mod_cooking_desc = Механика готовки: верстак на кухне home_kitchen с рецептами (например, волчье мясо в рационы), панель статистики рационов и сценар готовки.
ui/cook/cook = Готовить
ui/cook/close = Выйти
ui/cook/title = Приготовление еды
ui/cook/recipe_time = {0} минут
ui/cook/recipe_out = Результат приготовления: {0}
ui/diner/rationcount = Пайков: {0}
ui/diner/rationday = Потребление в сутки: {0}
ui/diner/rationmax = Запасов хватит на {0} дней
items/food/ration/name = Рацион
items/food/ration/desc = Единица суточного рациона для одного человека
items/food/wolf_meat/name = Волчья вырезка
items/food/wolf_meat/desc = Сырое мясо волка
items/resource/branches/name = Ветки
items/resource/branches/desc = Топливо для костра
recipe/wolf_meat_to_ration/name = Рацион из волчьего мяса
recipe/wolf_meat_to_ration/desc = Рецепт описывает как правильно приготовить волчатину, чтобы безопасно употребить её в пищу
items/recipe/wolf_meat_to_ration/name = Рецепт: рацион из волчьего мяса
items/recipe/wolf_meat_to_ration/desc = Учит готовить из волчатины рационы, которые безопасно есть
mod_cooking/rations_per_character = Рационов на персонажа в сутки
+3 -3
View File
@@ -1,3 +1,3 @@
rooms/kitchen/prompt = A room equipped as a kitchen
rooms/kitchen/opt_exit = Leave
rooms/kitchen/opt_cook = Cook
rooms/kitchen/prompt = A room equipped as a kitchen
rooms/kitchen/opt_exit = Leave
rooms/kitchen/opt_cook = Cook
+3 -3
View File
@@ -1,3 +1,3 @@
rooms/kitchen/prompt = Комната оборудованная под кухню
rooms/kitchen/opt_exit = Выйти
rooms/kitchen/opt_cook = Готовить
rooms/kitchen/prompt = Комната оборудованная под кухню
rooms/kitchen/opt_exit = Выйти
rooms/kitchen/opt_cook = Готовить
+27 -27
View File
@@ -1,28 +1,28 @@
{
"Kind": "recipe",
"Items": [
{
"Id": "recipe/wolf_meat_to_ration",
"Name": "recipe/wolf_meat_to_ration/name",
"Description": "recipe/wolf_meat_to_ration/desc",
"Type": "Cooking",
"Time": 15,
"Input": [
{
"Id": "food/wolf_meat",
"Count": 1
},
{
"Id": "resource/branches",
"Count": 2
}
],
"Output": [
{
"Id": "food/ration",
"Count": 1
}
]
}
]
{
"Kind": "recipe",
"Items": [
{
"Id": "recipe/wolf_meat_to_ration",
"Name": "recipe/wolf_meat_to_ration/name",
"Description": "recipe/wolf_meat_to_ration/desc",
"Type": "Cooking",
"Time": 15,
"Input": [
{
"Id": "food/wolf_meat",
"Count": 1
},
{
"Id": "resource/branches",
"Count": 2
}
],
"Output": [
{
"Id": "food/ration",
"Count": 1
}
]
}
]
}
+56 -56
View File
@@ -1,56 +1,56 @@
using System.Collections.Generic;
using Cthangover.Core.Mods;
using Cthangover.Core.Settings;
namespace Cthangover.Cooking
{
/// <summary>
/// Exposes a user-configurable setting for the number of rations
/// consumed per character per in-game day. Registered automatically
/// via <see cref="ModSettingsRegistry"/> when the cooking mod
/// assembly loads.
///
/// The static <see cref="RationsPerCharacter"/> property is the
/// canonical source of truth shared with <c>RationStatisticsPanel</c>
/// and any future consumption logic. It is updated by the core on
/// boot (from persisted JSON) and on every UI change.
/// </summary>
public class CookingSettings : IModSettings
{
/// <summary>
/// Current value for rations consumed per character per day.
/// Default is 1. Updated by <see cref="ReadValues"/> on boot
/// and whenever the player changes the setting in the menu.
/// </summary>
public static int RationsPerCharacter { get; private set; } = 1;
public IReadOnlyList<ModSettingDefinition> GetDefinitions()
{
return new List<ModSettingDefinition>
{
new()
{
Key = "rations_per_character",
Name = "mod_cooking/rations_per_character",
Type = SettingType.Slider,
DefaultValue = "1",
Min = 1f,
Max = 10f,
Step = 1f,
},
};
}
public void WriteValues(DataBlob blob)
{
blob.SetInt("rations_per_character", RationsPerCharacter);
}
public void ReadValues(DataBlob blob)
{
RationsPerCharacter = blob.GetInt("rations_per_character", 1);
if (RationsPerCharacter < 1)
RationsPerCharacter = 1;
}
}
}
using System.Collections.Generic;
using Cthangover.Core.Mods;
using Cthangover.Core.Settings;
namespace Cthangover.Cooking
{
/// <summary>
/// Exposes a user-configurable setting for the number of rations
/// consumed per character per in-game day. Registered automatically
/// via <see cref="ModSettingsRegistry"/> when the cooking mod
/// assembly loads.
///
/// The static <see cref="RationsPerCharacter"/> property is the
/// canonical source of truth shared with <c>RationStatisticsPanel</c>
/// and any future consumption logic. It is updated by the core on
/// boot (from persisted JSON) and on every UI change.
/// </summary>
public class CookingSettings : IModSettings
{
/// <summary>
/// Current value for rations consumed per character per day.
/// Default is 1. Updated by <see cref="ReadValues"/> on boot
/// and whenever the player changes the setting in the menu.
/// </summary>
public static int RationsPerCharacter { get; private set; } = 1;
public IReadOnlyList<ModSettingDefinition> GetDefinitions()
{
return new List<ModSettingDefinition>
{
new()
{
Key = "rations_per_character",
Name = "mod_cooking/rations_per_character",
Type = SettingType.Slider,
DefaultValue = "1",
Min = 1f,
Max = 10f,
Step = 1f,
},
};
}
public void WriteValues(DataBlob blob)
{
blob.SetInt("rations_per_character", RationsPerCharacter);
}
public void ReadValues(DataBlob blob)
{
RationsPerCharacter = blob.GetInt("rations_per_character", 1);
if (RationsPerCharacter < 1)
RationsPerCharacter = 1;
}
}
}
+64 -64
View File
@@ -1,65 +1,65 @@
using Cthangover.Cooking;
using System;
using Cthangover.Core.Settings;
using Cthangover.Core.UI;
using Godot;
using Cthangover.Cooking;
using System;
using Cthangover.Core.Settings;
using Cthangover.Core.UI;
using Godot;
using Cthangover.Mods.Interface.Base.Lists;
namespace Mods.Cooking.Rations
{
/// <summary>
/// Displays live ration statistics on the dinner/ration UI screen.
/// Shows the player the current ration count, how many rations are
/// consumed daily (one per character), and the maximum number of days
/// the party can survive on available rations. Listens to
/// <see cref="Core.Items.InventoryBag.Change"/> events to refresh
/// automatically whenever the inventory is modified.
/// </summary>
public class RationStatisticsPanel : Widget
{
private RichTextLabel label;
private Action<string, int> _onInventoryChange;
protected override void OnceConstruct()
{
label = GetNode<RichTextLabel>("RationMargin/RationLabel");
_onInventoryChange = (_, _) => UpdateInfo();
GameData.Instance.Runtime.Inventory.Change += _onInventoryChange;
}
protected override void ShowConstruct()
{
UpdateInfo();
}
protected override void OnceDestruct()
{
GameData.Instance.Runtime.Inventory.Change -= _onInventoryChange;
}
/// <summary>
/// Recomputes and refreshes the ration-statistics text.
/// Reads current ration inventory via <see cref="Core.Items.InventoryBag.CheckCount"/>
/// for <c>"food/ration"</c> and the total character count from
/// <see cref="CharacterData"/>. Formats three localized lines:
/// total rations, daily consumption, and remaining days
/// (rations divided by character count, clamped to 1 minimum).
/// </summary>
public void UpdateInfo()
{
if (label == null)
return;
var rationCount = GameData.Instance.Runtime.Inventory.CheckCount("food/ration");
var characterCount = GameData.Instance.Runtime.CharacterData.Characters.Count;
var perChar = CookingSettings.RationsPerCharacter;
var dailyConsumption = characterCount * perChar;
label.Text = string.Format(TranslationServer.Translate("ui/diner/rationcount"), rationCount) +
"\n" + string.Format(TranslationServer.Translate("ui/diner/rationday"), dailyConsumption) +
"\n" + string.Format(TranslationServer.Translate("ui/diner/rationmax"), rationCount / Mathf.Max(1, dailyConsumption));
}
}
}
namespace Mods.Cooking.Rations
{
/// <summary>
/// Displays live ration statistics on the dinner/ration UI screen.
/// Shows the player the current ration count, how many rations are
/// consumed daily (one per character), and the maximum number of days
/// the party can survive on available rations. Listens to
/// <see cref="Core.Items.InventoryBag.Change"/> events to refresh
/// automatically whenever the inventory is modified.
/// </summary>
public class RationStatisticsPanel : Widget
{
private RichTextLabel label;
private Action<string, int> _onInventoryChange;
protected override void OnceConstruct()
{
label = GetNode<RichTextLabel>("RationMargin/RationLabel");
_onInventoryChange = (_, _) => UpdateInfo();
GameData.Instance.Runtime.Inventory.Change += _onInventoryChange;
}
protected override void ShowConstruct()
{
UpdateInfo();
}
protected override void OnceDestruct()
{
GameData.Instance.Runtime.Inventory.Change -= _onInventoryChange;
}
/// <summary>
/// Recomputes and refreshes the ration-statistics text.
/// Reads current ration inventory via <see cref="Core.Items.InventoryBag.CheckCount"/>
/// for <c>"food/ration"</c> and the total character count from
/// <see cref="CharacterData"/>. Formats three localized lines:
/// total rations, daily consumption, and remaining days
/// (rations divided by character count, clamped to 1 minimum).
/// </summary>
public void UpdateInfo()
{
if (label == null)
return;
var rationCount = GameData.Instance.Runtime.Inventory.CheckCount("food/ration");
var characterCount = GameData.Instance.Runtime.CharacterData.Characters.Count;
var perChar = CookingSettings.RationsPerCharacter;
var dailyConsumption = characterCount * perChar;
label.Text = string.Format(TranslationServer.Translate("ui/diner/rationcount"), rationCount) +
"\n" + string.Format(TranslationServer.Translate("ui/diner/rationday"), dailyConsumption) +
"\n" + string.Format(TranslationServer.Translate("ui/diner/rationmax"), rationCount / Mathf.Max(1, dailyConsumption));
}
}
}
+70 -70
View File
@@ -1,71 +1,71 @@
using Cthangover.Core.Items;
using Cthangover.Core.Settings;
using Cthangover.Core.UI;
using Cthangover.Core.UI.Theming;
using Cthangover.Core.Utils;
using Godot;
using Cthangover.Core.Items;
using Cthangover.Core.Settings;
using Cthangover.Core.UI;
using Cthangover.Core.UI.Theming;
using Cthangover.Core.Utils;
using Godot;
using Cthangover.Mods.Interface.Base.Lists;
namespace Mods.Cooking.Workbench
{
/// <summary>
/// Renders a single ingredient row inside a <see cref="RecipeItemBehaviour"/>
/// on the cooking workbench. Displays the ingredient's item icon and the
/// required count. When <see cref="CheckAndUpdate"/> is called, compares
/// inventory count against the recipe requirement and tints the icon and
/// count text grey if the player lacks enough items.
/// </summary>
public class RecipeIconItemBehaviour : Widget
{
private static readonly Color NormalColor = UiTokens.InkBright;
private static readonly Color NotItemsColor = UiTokens.Muted;
private TextureRect img;
private Label txt;
private IIngredient ingredient;
protected override void OnceConstruct()
{
img = GetNode<TextureRect>("Img");
txt = GetNode<Label>("Txt");
}
/// <summary>
/// Binds this icon widget to a recipe ingredient definition.
/// Sets the icon texture from <c>ingredient.Item.Sprite</c> (logs an error
/// if the item reference is null) and displays the required count as text.
/// The <paramref name="hasItems"/> flag is currently unused but reserved
/// for future visual pre-initialization.
/// </summary>
public void Init(IIngredient ingredient, bool hasItems)
{
EnsureConstructed();
this.ingredient = ingredient;
if (ingredient.Item != null)
{
img.Texture = ingredient.Item.Sprite;
}
else
{
GameLogger.Log("MOD_TEST", $"RecipeIconItemBehaviour::Init ingredient.Item is NULL", LogLevel.Error);
}
txt.Text = ingredient.Count.ToString();
}
/// <summary>
/// Evaluates whether the player's inventory contains enough of the
/// required ingredient. Tints the icon and count text to
/// <c>NormalColor</c> (bright ink) when satisfied or <c>NotItemsColor</c>
/// (muted) when insufficient. Called by the parent
/// <see cref="RecipeItemBehaviour"/> during state refresh.
/// </summary>
/// <returns><c>true</c> if inventory meets or exceeds the required count.</returns>
public bool CheckAndUpdate()
{
var result = GameData.Instance.Runtime.Inventory.CheckCount(ingredient.Item) >= ingredient.Count;
txt.AddThemeColorOverride("font_color", result ? NormalColor : NotItemsColor);
img.Modulate = result ? UiTokens.White : NotItemsColor;
return result;
}
}
}
namespace Mods.Cooking.Workbench
{
/// <summary>
/// Renders a single ingredient row inside a <see cref="RecipeItemBehaviour"/>
/// on the cooking workbench. Displays the ingredient's item icon and the
/// required count. When <see cref="CheckAndUpdate"/> is called, compares
/// inventory count against the recipe requirement and tints the icon and
/// count text grey if the player lacks enough items.
/// </summary>
public class RecipeIconItemBehaviour : Widget
{
private static readonly Color NormalColor = UiTokens.InkBright;
private static readonly Color NotItemsColor = UiTokens.Muted;
private TextureRect img;
private Label txt;
private IIngredient ingredient;
protected override void OnceConstruct()
{
img = GetNode<TextureRect>("Img");
txt = GetNode<Label>("Txt");
}
/// <summary>
/// Binds this icon widget to a recipe ingredient definition.
/// Sets the icon texture from <c>ingredient.Item.Sprite</c> (logs an error
/// if the item reference is null) and displays the required count as text.
/// The <paramref name="hasItems"/> flag is currently unused but reserved
/// for future visual pre-initialization.
/// </summary>
public void Init(IIngredient ingredient, bool hasItems)
{
EnsureConstructed();
this.ingredient = ingredient;
if (ingredient.Item != null)
{
img.Texture = ingredient.Item.Sprite;
}
else
{
GameLogger.Log("MOD_TEST", $"RecipeIconItemBehaviour::Init ingredient.Item is NULL", LogLevel.Error);
}
txt.Text = ingredient.Count.ToString();
}
/// <summary>
/// Evaluates whether the player's inventory contains enough of the
/// required ingredient. Tints the icon and count text to
/// <c>NormalColor</c> (bright ink) when satisfied or <c>NotItemsColor</c>
/// (muted) when insufficient. Called by the parent
/// <see cref="RecipeItemBehaviour"/> during state refresh.
/// </summary>
/// <returns><c>true</c> if inventory meets or exceeds the required count.</returns>
public bool CheckAndUpdate()
{
var result = GameData.Instance.Runtime.Inventory.CheckCount(ingredient.Item) >= ingredient.Count;
txt.AddThemeColorOverride("font_color", result ? NormalColor : NotItemsColor);
img.Modulate = result ? UiTokens.White : NotItemsColor;
return result;
}
}
}